Version 2.6.0-dev.5.0
Merge commit '5c106e3098bb64139e6c91cd5a57b82bbe662111' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec7b523..81f49ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,16 +31,20 @@
#### Linter
-The Linter was updated to `0.1.98`, which includes:
+The Linter was updated to `0.1.99`, 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`
-* rule template generation improvements
-* new lint: `avoid_equals_and_hash_code_on_mutable_classes`
-* extended `avoid_slow_async_io` to flag async `Directory` methods
+* fixed unsafe casts in `overridden_fields`
+* (internal) migration to the mock SDK in `package:analyzer` for testing
+* fixed empty argument list access in `use_full_hex_values_for_flutter_color_fix`
+* new lint: `prefer_relative_imports`
+* improved messages for `await_only_futures`
+
+## 2.5.1 - 2019-09-27
+
+This is a patch release that prevents type inference failures in the analyzer
+(Issue [38365][]).
+
+[38365]: https://github.com/dart-lang/sdk/issues/38365
## 2.5.0 - 2019-09-10
diff --git a/DEPS b/DEPS
index 60b6900..3090e38 100644
--- a/DEPS
+++ b/DEPS
@@ -99,7 +99,7 @@
"intl_tag": "0.15.7",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.98",
+ "linter_tag": "0.1.99",
"logging_tag": "0.11.3+2",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_tag": "2.1.1",
@@ -136,7 +136,7 @@
"test_descriptor_tag": "1.1.1",
"test_process_tag": "1.0.3",
"term_glyph_tag": "1.0.1",
- "test_reflective_loader_tag": "0.1.8",
+ "test_reflective_loader_tag": "0.1.9",
"test_tag": "test-v1.6.4",
"tflite_native_rev": "06e533a9747306d1114c53427cc67eda080f51f9",
"typed_data_tag": "1.1.6",
@@ -174,7 +174,7 @@
Var("dart_root") + "/tools/sdks": {
"packages": [{
"package": "dart/dart-sdk/${{platform}}",
- "version": "version:2.6.0-dev.3.0",
+ "version": "version:2.6.0-dev.4.0",
}],
"dep_type": "cipd",
},
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index abfe139..b7a443f 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -216,18 +216,25 @@
return []
local_root = input_api.change.RepositoryRoot()
- layering_check = imp.load_source(
- 'layering_check',
- os.path.join(local_root, 'runtime', 'tools', 'layering_check.py'))
- errors = layering_check.DoCheck(local_root)
+ compiler_layering_check = imp.load_source(
+ 'compiler_layering_check',
+ os.path.join(local_root, 'runtime', 'tools',
+ 'compiler_layering_check.py'))
+ errors = compiler_layering_check.DoCheck(local_root)
+ embedder_layering_check = imp.load_source(
+ 'embedder_layering_check',
+ os.path.join(local_root, 'runtime', 'tools',
+ 'embedder_layering_check.py'))
+ errors += embedder_layering_check.DoCheck(local_root)
if errors:
return [
output_api.PresubmitError(
'Layering check violation for C++ sources.',
long_text='\n'.join(errors))
]
- else:
- return []
+
+ return []
+
def _CheckClangTidy(input_api, output_api):
"""Run clang-tidy on VM changes."""
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 109e3fc..e5254c7 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -130,6 +130,10 @@
# Compile for Thread Sanitizer to find threading bugs.
is_tsan = false
+
+ # Whether to use the NNBD fork of the SDK core libraries.
+ # TODO(rnystrom): Remove this when the fork has been merged back in.
+ use_nnbd = false
}
# =============================================================================
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 ef4751b..0b33895 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,12 +6,13 @@
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/highlight_css.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.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/highlight_js.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -216,30 +217,46 @@
/// Generate output into the given [folder].
void _generateOutput(OverlayResourceProvider provider, Folder folder) async {
- List<LibraryInfo> libraryInfos =
- await InfoBuilder(instrumentationListener.data, listener)
- .explainMigration();
+ // Remove any previously generated output.
+ folder.getChildren().forEach((resource) => resource.delete());
+ // Gather the data needed in order to produce the output.
+ InfoBuilder infoBuilder =
+ InfoBuilder(instrumentationListener.data, listener);
+ List<UnitInfo> unitInfos = await infoBuilder.explainMigration();
var pathContext = provider.pathContext;
MigrationInfo migrationInfo =
- MigrationInfo(libraryInfos, pathContext, includedRoot);
- for (LibraryInfo info in libraryInfos) {
- assert(info.units.isNotEmpty);
- String libraryPath =
- pathContext.setExtension(info.units.first.path, '.html');
- String relativePath =
- pathContext.relative(libraryPath, from: includedRoot);
- List<String> directories =
- pathContext.split(pathContext.dirname(relativePath));
- for (int i = 0; i < directories.length; i++) {
- String directory = pathContext.joinAll(directories.sublist(0, i + 1));
- folder.getChildAssumingFolder(directory).create();
- }
- File output =
- provider.getFile(pathContext.join(folder.path, relativePath));
- String rendered = InstrumentationRenderer(info, migrationInfo).render();
+ MigrationInfo(unitInfos, pathContext, includedRoot);
+ PathMapper pathMapper = PathMapper(provider, folder.path, includedRoot);
+
+ /// Produce output for the compilation unit represented by the [unitInfo].
+ void render(UnitInfo unitInfo) {
+ File output = provider.getFile(pathMapper.map(unitInfo.path));
+ output.parent.create();
+ String rendered =
+ InstrumentationRenderer(unitInfo, migrationInfo, pathMapper).render();
output.writeAsStringSync(rendered);
}
- // Generate resource files:
+
+ // Generate the files in the package being migrated.
+ for (UnitInfo unitInfo in unitInfos) {
+ render(unitInfo);
+ }
+ // Generate other dart files.
+ for (UnitInfo unitInfo in infoBuilder.unitMap.values) {
+ if (!unitInfos.contains(unitInfo)) {
+ if (unitInfo.content == null) {
+ try {
+ unitInfo.content =
+ provider.getFile(unitInfo.path).readAsStringSync();
+ } catch (_) {
+ // If we can't read the content of the file, then skip it.
+ continue;
+ }
+ }
+ render(unitInfo);
+ }
+ }
+ // Generate resource files.
File highlightJsOutput =
provider.getFile(pathContext.join(folder.path, 'highlight.pack.js'));
highlightJsOutput.writeAsStringSync(decodeHighlightJs());
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
index 694a210..950e06f 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.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';
@@ -10,9 +11,12 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show Location, SourceEdit, SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
@@ -48,20 +52,60 @@
/// Return the migration information for all of the libraries that were
/// migrated.
- Future<List<LibraryInfo>> explainMigration() async {
- Map<Source, SourceInformation> sourceInfo = info.sourceInformation;
- List<LibraryInfo> libraries = [];
- for (Source source in sourceInfo.keys) {
+ Future<List<UnitInfo>> explainMigration() async {
+ Map<Source, SourceInformation> sourceInfoMap = info.sourceInformation;
+ List<UnitInfo> units = [];
+ for (Source source in sourceInfoMap.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));
+ ResolvedLibraryResult result =
+ await session.getResolvedLibrary(filePath);
+ SourceInformation sourceInfo = sourceInfoMap[source];
+ for (ResolvedUnitResult unitResult in result.units) {
+ SourceFileEdit edit =
+ listener.sourceChange.getFileEdit(unitResult.path);
+ units.add(_explainUnit(sourceInfo, unitResult, edit));
+ }
}
}
- return libraries;
+ return units;
+ }
+
+ /// Return details for a fix built from the given [edge], or `null` if the
+ /// edge does not have an origin.
+ String _buildDescriptionForDestination(AstNode node) {
+ // Other found types:
+ // - ConstructorDeclaration
+ if (node.parent is FormalParameterList) {
+ return "A nullable value can't be passed as an argument";
+ } else {
+ return "A nullable value can't be used here";
+ }
+ }
+
+ /// Return details for a fix built from the given [edge], or `null` if the
+ /// edge does not have an origin.
+ String _buildDescriptionForOrigin(AstNode node) {
+ String /*!*/ description;
+ if (node.parent is ArgumentList) {
+ if (node is NullLiteral) {
+ description = "An explicit 'null' is passed as an argument";
+ } else {
+ description = "A nullable value is explicitly passed as an argument";
+ }
+ } else {
+ if (node is NullLiteral) {
+ description = "An explicit 'null' is assigned";
+ } else {
+ description = "A nullable value is assigned";
+ }
+ }
+ if (_inTestCode(node)) {
+ description += " in test code";
+ }
+ return description;
}
/// Compute the details for the fix with the given [fixInfo].
@@ -70,28 +114,26 @@
for (FixReasonInfo reason in fixInfo.reasons) {
if (reason is NullabilityNodeInfo) {
for (EdgeInfo edge in reason.upstreamEdges) {
- EdgeOriginInfo origin = info.edgeOrigin[edge];
- if (origin != null) {
- AstNode node = origin.node;
- if (node.parent is ArgumentList) {
- if (node is NullLiteral) {
- details.add(RegionDetail(
- 'null is explicitly passed as an argument.',
- _targetFor(origin)));
- } else {
- details.add(RegionDetail(
- 'A nullable value is explicitly passed as an argument.',
- _targetFor(origin)));
- }
- } else {
- details.add(RegionDetail(
- 'A nullable value is assigned.', _targetFor(origin)));
+ if (edge.isTriggered) {
+ EdgeOriginInfo origin = info.edgeOrigin[edge];
+ if (origin != null) {
+ // TODO(brianwilkerson) If the origin is an InheritanceOrigin then
+ // the node is the method declaration in the subclass and we want
+ // to link to the corresponding parameter in the declaration in
+ // the superclass.
+ details.add(RegionDetail(_buildDescriptionForOrigin(origin.node),
+ _targetForNode(origin.source.fullName, origin.node)));
}
}
}
} else if (reason is EdgeInfo) {
- // TODO(brianwilkerson) Implement this after finding an example whose
- // reason is an edge.
+ NullabilityNodeInfo destination = reason.destinationNode;
+ var nodeInfo = info.nodeInfoFor(destination);
+ if (nodeInfo != null) {
+ details.add(RegionDetail(
+ _buildDescriptionForDestination(nodeInfo.astNode),
+ _targetForNode(nodeInfo.filePath, nodeInfo.astNode)));
+ }
} else {
throw UnimplementedError(
'Unexpected class of reason: ${reason.runtimeType}');
@@ -100,24 +142,41 @@
return details;
}
- /// 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(sourceInfo, unit, edit));
- }
- return LibraryInfo(units);
+ /// Return the navigation sources for the unit associated with the [result].
+ List<NavigationSource> _computeNavigationSources(ResolvedUnitResult result) {
+ NavigationCollectorImpl collector = new NavigationCollectorImpl();
+ computeDartNavigation(
+ result.session.resourceProvider, collector, result.unit, null, null);
+ collector.createRegions();
+ List<String> files = collector.files;
+ List<protocol.NavigationRegion> regions = collector.regions;
+ List<protocol.NavigationTarget> rawTargets = collector.targets;
+ List<NavigationTarget> convertedTargets =
+ List<NavigationTarget>(rawTargets.length);
+ return regions.map((region) {
+ List<int> targets = region.targets;
+ if (targets.isEmpty) {
+ throw StateError('Targets is empty');
+ }
+ NavigationTarget target = convertedTargets[targets[0]];
+ if (target == null) {
+ protocol.NavigationTarget rawTarget = rawTargets[targets[0]];
+ target = _targetFor(
+ files[rawTarget.fileIndex], rawTarget.offset, rawTarget.length);
+ convertedTargets[targets[0]] = target;
+ }
+ return NavigationSource(region.offset, region.length, target);
+ }).toList();
}
- /// Return the migration information for the given unit.
- UnitInfo _explainUnit(SourceInformation sourceInfo, ParsedUnitResult result,
+ /// Return the migration information for the unit associated with the
+ /// [result].
+ UnitInfo _explainUnit(SourceInformation sourceInfo, ResolvedUnitResult result,
SourceFileEdit fileEdit) {
UnitInfo unitInfo = _unitForPath(result.path);
+ if (unitInfo.sources == null) {
+ unitInfo.sources = _computeNavigationSources(result);
+ }
String content = result.content;
// [fileEdit] is null when a file has no edits.
if (fileEdit != null) {
@@ -166,17 +225,35 @@
return null;
}
- /// Return the navigation target corresponding to the given [origin].
- NavigationTarget _targetFor(EdgeOriginInfo origin) {
- AstNode node = origin.node;
- String filePath = origin.source.fullName;
+ /// Return `true` if the given [node] is from a compilation unit within the
+ /// 'test' directory of the package.
+ bool _inTestCode(AstNode node) {
+ // TODO(brianwilkerson) Generalize this.
+ CompilationUnit unit = node.thisOrAncestorOfType<CompilationUnit>();
+ CompilationUnitElement unitElement = unit?.declaredElement;
+ if (unitElement == null) {
+ return false;
+ }
+ String filePath = unitElement.source.fullName;
+ var resourceProvider = unitElement.session.resourceProvider;
+ return resourceProvider.pathContext.split(filePath).contains('test');
+ }
+
+ /// Return the navigation target in the file with the given [filePath] at the
+ /// given [offset] ans with the given [length].
+ NavigationTarget _targetFor(String filePath, int offset, int length) {
UnitInfo unitInfo = _unitForPath(filePath);
- NavigationTarget target =
- NavigationTarget(filePath, node.offset, node.length);
+ NavigationTarget target = NavigationTarget(filePath, offset, length);
unitInfo.targets.add(target);
return target;
}
+ /// Return the navigation target corresponding to the given [node] in the file
+ /// with the given [filePath].
+ NavigationTarget _targetForNode(String filePath, AstNode node) {
+ return _targetFor(filePath, node.offset, node.length);
+ }
+
/// Return the unit info for the file at the given [path].
UnitInfo _unitForPath(String path) {
return unitMap.putIfAbsent(path, () => UnitInfo(path));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
index 1e60891..e1b1938 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
@@ -34,6 +34,55 @@
/// Initialize a newly created holder of instrumentation information.
InstrumentationInformation();
+
+ /// Return information about the given [node].
+ NodeInformation nodeInfoFor(NullabilityNodeInfo node) {
+ for (MapEntry<Source, SourceInformation> sourceEntry
+ in sourceInformation.entries) {
+ SourceInformation sourceInfo = sourceEntry.value;
+ for (MapEntry<AstNode, DecoratedTypeInfo> entry
+ in sourceInfo.implicitReturnType.entries) {
+ if (entry.value.node == node) {
+ return NodeInformation(
+ sourceEntry.key.fullName, entry.key, entry.value);
+ }
+ }
+ for (MapEntry<AstNode, DecoratedTypeInfo> entry
+ in sourceInfo.implicitType.entries) {
+ if (entry.value.node == node) {
+ return NodeInformation(
+ sourceEntry.key.fullName, entry.key, entry.value);
+ }
+ }
+ for (MapEntry<AstNode, List<DecoratedTypeInfo>> entry
+ in sourceInfo.implicitTypeArguments.entries) {
+ for (var type in entry.value) {
+ if (type.node == node) {
+ return NodeInformation(sourceEntry.key.fullName, entry.key, type);
+ }
+ }
+ }
+ }
+ // The loop below doesn't help because we still don't have access to an AST
+ // node.
+// for (MapEntry<Element, DecoratedTypeInfo> entry in externalDecoratedType.entries) {
+// if (entry.value.node == node) {
+// return NodeInformation(null, null, entry.value);
+// }
+// }
+ return null;
+ }
+}
+
+/// The instrumentation information about a [NullabilityNodeInfo].
+class NodeInformation {
+ final String filePath;
+
+ final AstNode astNode;
+
+ final DecoratedTypeInfo decoratedType;
+
+ NodeInformation(this.filePath, this.astNode, this.decoratedType);
}
/// The instrumentation information gathered from the migration engine that is
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 6735746..7e3812a 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
@@ -1,137 +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.
+
import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
import 'package:meta/meta.dart';
import 'package:mustache/mustache.dart' as mustache;
import 'package:path/path.dart' as path;
-/// Instrumentation display output for a library that was migrated to use
-/// non-nullable types.
-class InstrumentationRenderer {
- /// Display information for a library.
- final LibraryInfo libraryInfo;
-
- /// Information for a whole migration, so that libraries can reference each
- /// other.
- final MigrationInfo migrationInfo;
-
- /// Creates an output object for the given library info.
- InstrumentationRenderer(this.libraryInfo, this.migrationInfo);
-
- /// Builds an HTML view of the instrumentation information in [libraryInfo].
- String render() {
- int previousIndex = 0;
- Map<String, dynamic> mustacheContext = {
- 'units': <Map<String, dynamic>>[],
- 'links': migrationInfo.libraryLinks(libraryInfo),
- 'highlightJsPath': migrationInfo.highlightJsPath(libraryInfo),
- 'highlightStylePath': migrationInfo.highlightStylePath(libraryInfo),
- };
- for (var compilationUnit in libraryInfo.units) {
- // 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.
- regions.add({
- 'modified': false,
- 'content':
- compilationUnit.content.substring(previousIndex, region.offset)
- });
- previousIndex = region.offset + region.length;
- }
- 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.
- regions.add({
- 'modified': false,
- 'content': compilationUnit.content.substring(previousIndex)
- });
- }
- mustacheContext['units']
- .add({'path': compilationUnit.path, 'regions': regions});
- }
- return _template.renderString(mustacheContext);
- }
-}
-
-/// A class storing rendering information for an entire migration report.
-///
-/// This generally provides one [InstrumentationRenderer] (for one library)
-/// with information about the rest of the libraries represented in the
-/// instrumentation output.
-class MigrationInfo {
- /// The information about the libraries that are are migrated.
- final List<LibraryInfo> libraries;
-
- /// The resource provider's path context.
- final path.Context pathContext;
-
- /// The filesystem root used to create relative paths for each unit.
- final String includedRoot;
-
- MigrationInfo(this.libraries, this.pathContext, this.includedRoot);
-
- /// Generate mustache context for library links, for navigation in the
- /// instrumentation document for [thisLibrary].
- List<Map<String, Object>> libraryLinks(LibraryInfo thisLibrary) {
- return [
- for (var library in libraries)
- {
- 'name': _computeName(library),
- 'isLink': library != thisLibrary,
- if (library != thisLibrary)
- 'href': _pathTo(library, source: thisLibrary)
- }
- ];
- }
-
- /// Return the path to [library] from [includedRoot], to be used as a display
- /// name for a library.
- String _computeName(LibraryInfo library) =>
- pathContext.relative(library.units.first.path, from: includedRoot);
-
- /// The path to [target], relative to [from].
- String _pathTo(LibraryInfo target, {@required LibraryInfo source}) {
- assert(target.units.isNotEmpty);
- assert(source.units.isNotEmpty);
- String targetPath =
- pathContext.setExtension(target.units.first.path, '.html');
- String sourceDir = pathContext.dirname(source.units.first.path);
- return pathContext.relative(targetPath, from: sourceDir);
- }
-
- /// The path to the highlight.js script, relative to [libraryInfo].
- String highlightJsPath(LibraryInfo libraryInfo) =>
- pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
- from: pathContext.dirname(libraryInfo.units.first.path));
-
- /// The path to the highlight.js stylesheet, relative to [libraryInfo].
- String highlightStylePath(LibraryInfo libraryInfo) =>
- pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
- from: pathContext.dirname(libraryInfo.units.first.path));
-}
-
/// A mustache template for one library's instrumentation output.
mustache.Template _template = mustache.Template(r'''
<html>
<head>
<title>Non-nullable fix instrumentation report</title>
- <script src="{{ highlightJsPath }}"></script>
+<!-- <script src="{{ highlightJsPath }}"></script>-->
+ <script>
+ function highlightTarget() {
+ var url = document.URL;
+ var index = url.lastIndexOf("#");
+ if (index >= 0) {
+ var name = url.substring(index + 1);
+ var anchor = document.getElementById(name);
+ if (anchor != null) {
+ anchor.className = "target";
+ }
+ }
+ }
+ </script>
<link rel="stylesheet" href="{{ highlightStylePath }}">
<style>
+a:link {
+ color: #000000;
+ text-decoration-line: none;
+}
+
+a:visited {
+ color: #000000;
+ text-decoration-line: none;
+}
+
body {
font-family: sans-serif;
padding: 1em;
@@ -142,6 +50,12 @@
font-weight: bold;
}
+.code {
+ position: absolute;
+ left: 0.5em;
+ top: 0.5em;
+}
+
.content {
font-family: monospace;
position: relative;
@@ -181,16 +95,22 @@
top: 100%;
visibility: hidden;
white-space: normal;
- width: 200px;
+ width: 400px;
z-index: 1;
}
.region:hover .tooltip {
visibility: visible;
}
+
+.target {
+ background-color: #FFFFFF;
+ position: relative;
+ visibility: visible;
+}
</style>
</head>
- <body>
+ <body onload="highlightTarget()">
<h1>Non-nullable fix instrumentation report</h1>
<p><em>Well-written introduction to this report.</em></p>
<div class="navigation">
@@ -203,20 +123,30 @@
{{# units }}'''
'<h2>{{{ path }}}</h2>'
'<div class="content">'
- '<div class="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="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>'
+ '<div class ="code">'
+ '{{! Write the file content, modified to include navigation information, }}'
+ '{{! both anchors and links. }}'
+ '{{{ navContent }}}'
'</div>'
'<div class="regions">'
- '{{! The regions are then printed again, overlaying the first copy of the }}'
- '{{! content, to provide tooltips for modified regions. }}'
+ '{{! The regions are then written again, overlaying the first two copies }}'
+ '{{! 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 }}'
+ '<span class="tooltip">{{ explanation }}<ul>'
+ '{{# details }}'
+ '<li>'
+ '<a href="{{ target }}">{{ description }}</a>'
+ '</li>'
+ '{{/ details }}</ul></span></span>{{/ modified }}'
'{{/ regions }}'
'</div></div>'
r'''
@@ -230,3 +160,217 @@
</script>
</body>
</html>''');
+
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
+class InstrumentationRenderer {
+ /// Display information for a compilation unit.
+ final UnitInfo unitInfo;
+
+ /// Information for a whole migration, so that libraries can reference each
+ /// other.
+ final MigrationInfo migrationInfo;
+
+ /// An object used to map the file paths of analyzed files to the file paths
+ /// of the HTML files used to view the content of those files.
+ final PathMapper pathMapper;
+
+ /// Creates an output object for the given library info.
+ InstrumentationRenderer(this.unitInfo, this.migrationInfo, this.pathMapper);
+
+ /// Builds an HTML view of the instrumentation information in [unitInfo].
+ String render() {
+ Map<String, dynamic> mustacheContext = {
+ 'units': <Map<String, dynamic>>[],
+ 'links': migrationInfo.unitLinks(unitInfo),
+ 'highlightJsPath': migrationInfo.highlightJsPath(unitInfo),
+ 'highlightStylePath': migrationInfo.highlightStylePath(unitInfo),
+ 'navContent': _computeNavigationContent(unitInfo),
+ };
+ mustacheContext['units'].add({
+ 'path': unitInfo.path,
+ 'regions': _computeRegions(unitInfo),
+ });
+ return _template.renderString(mustacheContext);
+ }
+
+ /// Return the content of the file with navigation links and anchors added.
+ String _computeNavigationContent(UnitInfo unitInfo) {
+ String content = unitInfo.content;
+ OffsetMapper mapper = unitInfo.offsetMapper;
+ List<NavigationRegion> regions = []
+ ..addAll(unitInfo.sources ?? <NavigationSource>[])
+ ..addAll(unitInfo.targets);
+ regions.sort((first, second) {
+ int offsetComparison = first.offset.compareTo(second.offset);
+ if (offsetComparison == 0) {
+ return first is NavigationSource ? -1 : 1;
+ }
+ return offsetComparison;
+ });
+
+ StringBuffer navContent = StringBuffer();
+ int previousOffset = 0;
+ for (int i = 0; i < regions.length; i++) {
+ NavigationRegion region = regions[i];
+ int offset = mapper.map(region.offset);
+ int length = region.length;
+ if (offset > previousOffset) {
+ // Write a non-target region.
+ navContent.write(content.substring(previousOffset, offset));
+ if (region is NavigationSource) {
+ if (i + 1 < regions.length &&
+ regions[i + 1].offset == region.offset) {
+ NavigationTarget target = region.target;
+ if (target == regions[i + 1]) {
+ // Add a target region. We skip the source because it links to
+ // itself, which is pointless.
+ navContent.write('<a id="o${region.offset}">');
+ navContent.write(content.substring(offset, offset + length));
+ navContent.write('</a>');
+ } else {
+ // Add a source and target region.
+ // TODO(brianwilkerson) Map the target's file path to the path of
+ // the corresponding html file. I'd like to do this by adding a
+ // `FilePathMapper` object so that it can't become inconsistent
+ // with the code used to decide where to write the html.
+ String htmlPath = pathMapper.map(target.filePath);
+ navContent.write('<a id="o${region.offset}" ');
+ navContent.write('href="$htmlPath#o${target.offset}">');
+ navContent.write(content.substring(offset, offset + length));
+ navContent.write('</a>');
+ }
+ i++;
+ } else {
+ // Add a source region.
+ NavigationTarget target = region.target;
+ String htmlPath = pathMapper.map(target.filePath);
+ navContent.write('<a href="$htmlPath#o${target.offset}">');
+ navContent.write(content.substring(offset, offset + length));
+ navContent.write('</a>');
+ }
+ } else {
+ // Add a target region.
+ navContent.write('<a id="o${region.offset}">');
+ navContent.write(content.substring(offset, offset + length));
+ navContent.write('</a>');
+ }
+ previousOffset = offset + length;
+ }
+ }
+ if (previousOffset < content.length) {
+ // Last non-target region.
+ navContent.write(content.substring(previousOffset));
+ }
+ return navContent.toString();
+ }
+
+ /// Return a list of Mustache context, based on the [unitInfo] for both
+ /// unmodified and modified regions:
+ ///
+ /// * 'modified': Whether this region represents modified source, or
+ /// unmodified.
+ /// * 'content': The textual content of this region.
+ /// * 'explanation': The Mustache context for the tooltip explaining why the
+ /// content in this region was modified.
+ List<Map> _computeRegions(UnitInfo unitInfo) {
+ String content = unitInfo.content;
+ List<Map> regions = [];
+ int previousOffset = 0;
+ for (var region in unitInfo.regions) {
+ int offset = region.offset;
+ int length = region.length;
+ if (offset > previousOffset) {
+ // Display a region of unmodified content.
+ regions.add({
+ 'modified': false,
+ 'content': content.substring(previousOffset, offset),
+ });
+ previousOffset = offset + length;
+ }
+ List<Map> details = [];
+ for (var detail in region.details) {
+ details.add({
+ 'description': detail.description,
+ 'target': _uriForTarget(detail.target),
+ });
+ }
+ regions.add({
+ 'modified': true,
+ 'content': content.substring(offset, offset + length),
+ 'explanation': region.explanation,
+ 'details': details,
+ });
+ }
+ if (previousOffset < content.length) {
+ // Last region of unmodified content.
+ regions.add({
+ 'modified': false,
+ 'content': content.substring(previousOffset),
+ });
+ }
+ return regions;
+ }
+
+ /// Return the URL that will navigate to the given [target].
+ String _uriForTarget(NavigationTarget target) {
+ path.Context pathContext = migrationInfo.pathContext;
+ String targetPath = pathContext.setExtension(target.filePath, '.html');
+ String sourceDir = pathContext.dirname(unitInfo.path);
+ String relativePath = pathContext.relative(targetPath, from: sourceDir);
+ return '$relativePath#o${target.offset.toString()}';
+ }
+}
+
+/// A class storing rendering information for an entire migration report.
+///
+/// This generally provides one [InstrumentationRenderer] (for one library)
+/// with information about the rest of the libraries represented in the
+/// instrumentation output.
+class MigrationInfo {
+ /// The information about the compilation units that are are migrated.
+ final List<UnitInfo> units;
+
+ /// The resource provider's path context.
+ final path.Context pathContext;
+
+ /// The filesystem root used to create relative paths for each unit.
+ final String includedRoot;
+
+ MigrationInfo(this.units, this.pathContext, this.includedRoot);
+
+ /// The path to the highlight.js script, relative to [unitInfo].
+ String highlightJsPath(UnitInfo unitInfo) =>
+ pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
+ from: pathContext.dirname(unitInfo.path));
+
+ /// The path to the highlight.js stylesheet, relative to [unitInfo].
+ String highlightStylePath(UnitInfo unitInfo) =>
+ pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
+ from: pathContext.dirname(unitInfo.path));
+
+ /// Generate mustache context for unit links, for navigation in the
+ /// instrumentation document for [thisUnit].
+ List<Map<String, Object>> unitLinks(UnitInfo thisUnit) {
+ return [
+ for (var unit in units)
+ {
+ 'name': _computeName(unit),
+ 'isLink': unit != thisUnit,
+ if (unit != thisUnit) 'href': _pathTo(target: unit, source: thisUnit)
+ }
+ ];
+ }
+
+ /// Return the path to [unit] from [includedRoot], to be used as a display
+ /// name for a library.
+ String _computeName(UnitInfo unit) =>
+ pathContext.relative(unit.path, from: includedRoot);
+
+ /// The path to [target], relative to [from].
+ String _pathTo({@required UnitInfo target, @required UnitInfo source}) {
+ String targetPath = pathContext.setExtension(target.path, '.html');
+ String sourceDir = pathContext.dirname(source.path);
+ return pathContext.relative(targetPath, from: sourceDir);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
index 7a66011..57f6002 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -15,19 +15,35 @@
LibraryInfo(this.units);
}
+/// A location from or to which a user might want to navigate.
+abstract class NavigationRegion {
+ /// The offset of the region.
+ final int offset;
+
+ /// The length of the region.
+ final int length;
+
+ /// Initialize a newly created link.
+ NavigationRegion(this.offset, this.length);
+}
+
+/// A location from which a user might want to navigate.
+class NavigationSource extends NavigationRegion {
+ /// The target to which the user should be navigated.
+ final NavigationTarget target;
+
+ /// Initialize a newly created link.
+ NavigationSource(int offset, int length, this.target) : super(offset, length);
+}
+
/// A location to which a user might want to navigate.
-class NavigationTarget {
+class NavigationTarget extends NavigationRegion {
/// The file containing the anchor.
final String filePath;
- /// The offset of the anchor.
- final int offset;
-
- /// The length of the anchor.
- final int length;
-
/// Initialize a newly created anchor.
- NavigationTarget(this.filePath, this.offset, this.length);
+ NavigationTarget(this.filePath, int offset, int length)
+ : super(offset, length);
@override
int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
@@ -85,6 +101,10 @@
/// them. The offsets in these regions are offsets into the post-edit content.
final List<RegionInfo> regions = [];
+ /// The navigation sources that are located in this file. The offsets in these
+ /// sources are offsets into the pre-edit content.
+ List<NavigationSource> sources;
+
/// The navigation targets that are located in this file. The offsets in these
/// targets are offsets into the pre-edit content.
final Set<NavigationTarget> targets = {};
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
new file mode 100644
index 0000000..f6939c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
@@ -0,0 +1,53 @@
+// 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/file_system/file_system.dart';
+import 'package:path/path.dart' as path;
+
+/// An object that can map the file paths of analyzed files to the file paths of
+/// the HTML files used to view the content of those files.
+class PathMapper {
+ /// The resource provider used to map paths.
+ ResourceProvider provider;
+
+ /// The absolute path of the folder that should contain all of the generated
+ /// HTML files.
+ final String outputFolder;
+
+ /// The root of the package containing the files being migrated.
+ final String packageRoot;
+
+ /// A table mapping the file paths of analyzed files to the file paths of the
+ /// HTML files used to view the content of those files.
+ final Map<String, String> pathMap = {};
+
+ /// The index to be used when creating the next synthetic file name.
+ int nextIndex = 1;
+
+ /// Initialize a newly created path mapper.
+ PathMapper(this.provider, this.outputFolder, this.packageRoot);
+
+ /// Return the path of the HTML file used to view the content of the analyzed
+ /// file with the given [path].
+ String map(String path) {
+ return pathMap.putIfAbsent(path, () => _computePathFor(path));
+ }
+
+ /// Return the path of the HTML file corresponding to the Dart file with the
+ /// given [path].
+ String _computePathFor(String filePath) {
+ path.Context context = provider.pathContext;
+ if (context.isWithin(packageRoot, filePath)) {
+ String packageParent = context.dirname(packageRoot);
+ String relative = context.relative(filePath, from: packageParent);
+ return context.join(
+ outputFolder, context.setExtension(relative, '.html'));
+ }
+ // TODO(brianwilkerson) Find a better mapping algorithm, that would produce
+ // a more readable URI. For example, have other packages and the sdk be
+ // parallel to the directory containing the files for the library being
+ // migrated.
+ return context.join(outputFolder, 'f${nextIndex++}.html');
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index 3b1d28a..995aa40 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -58,6 +58,10 @@
final renameOptionsSupport =
params.capabilities.textDocument?.rename?.prepareSupport ?? false;
+ final dynamicTextSyncRegistration = params
+ .capabilities.textDocument?.synchronization?.dynamicRegistration ??
+ false;
+
// When adding new capabilities to the server that may apply to specific file
// types, it's important to update
// [IntializedMessageHandler._performDynamicRegistration()] to notify
@@ -66,8 +70,13 @@
// requests where we have only partial support for some types).
server.capabilities = new ServerCapabilities(
Either2<TextDocumentSyncOptions, num>.t1(new TextDocumentSyncOptions(
- true,
- TextDocumentSyncKind.Incremental,
+ // The open/close and sync kind flags are registered dynamically if the
+ // client supports them, so these static registrations are based on whether
+ // the client supports dynamic registration.
+ dynamicTextSyncRegistration ? false : true,
+ dynamicTextSyncRegistration
+ ? TextDocumentSyncKind.None
+ : TextDocumentSyncKind.Incremental,
false,
false,
null,
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 6c51810..efbaa0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -134,9 +134,7 @@
static const FLUTTER_MOVE_UP =
const AssistKind('dart.assist.flutter.move.up', 30, "Move widget up");
static const FLUTTER_REMOVE_WIDGET = const AssistKind(
- 'dart.assist.flutter.removeWidget',
- 30,
- "Replace widget with its children");
+ 'dart.assist.flutter.removeWidget', 30, "Remove this widget");
static const FLUTTER_SWAP_WITH_CHILD = const AssistKind(
'dart.assist.flutter.swap.withChild', 30, "Swap with child");
static const FLUTTER_SWAP_WITH_PARENT = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 32e627e..3c3870b 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -65,6 +65,109 @@
(session.analysisContext.analysisOptions as AnalysisOptionsImpl)
.experimentStatus;
+ Future<ChangeBuilder> createBuilder_addDiagnosticPropertyReference() async {
+ final node = this.node;
+ if (node is! SimpleIdentifier) {
+ _coverageMarker();
+ return null;
+ }
+ SimpleIdentifier name = node;
+ final parent = node.parent;
+
+ DartType type;
+
+ // Getter.
+ if (parent is MethodDeclaration) {
+ MethodDeclaration methodDeclaration = parent;
+ var element = methodDeclaration.declaredElement;
+ if (element is PropertyAccessorElement) {
+ PropertyAccessorElement propertyAccessor = element;
+ type = propertyAccessor.returnType;
+ }
+ // Field.
+ } else if (parent is VariableDeclaration) {
+ VariableDeclaration variableDeclaration = parent;
+ final element = variableDeclaration.declaredElement;
+ if (element is FieldElement) {
+ FieldElement fieldElement = element;
+ type = fieldElement.type;
+ }
+ }
+
+ if (type == null) {
+ return null;
+ }
+
+ var constructorInvocation;
+ if (type.isDartCoreBool) {
+ constructorInvocation = 'DiagnosticsProperty<bool>';
+ } else if (type.isDartCoreInt) {
+ constructorInvocation = 'IntProperty';
+ } else if (type.isDartCoreDouble) {
+ constructorInvocation = 'DoubleProperty';
+ } else if (type.isDartCoreString) {
+ constructorInvocation = 'StringProperty';
+ } else if (isEnum(type)) {
+ constructorInvocation = 'EnumProperty';
+ }
+
+ // todo (pq): migrate type string generation to within change and use DartEditBuilder.writeType
+
+ if (constructorInvocation == null) {
+ return null;
+ }
+
+ ClassDeclaration classDeclaration =
+ parent.thisOrAncestorOfType<ClassDeclaration>();
+ final debugFillProperties =
+ classDeclaration.getMethod('debugFillProperties');
+ if (debugFillProperties != null) {
+ final body = debugFillProperties.body;
+ if (body is BlockFunctionBody) {
+ BlockFunctionBody functionBody = body;
+
+ var offset;
+ var prefix;
+ if (functionBody.block.statements.isEmpty) {
+ offset = functionBody.block.leftBracket.offset;
+ prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+ } else {
+ offset = functionBody.block.statements.last.endToken.offset;
+ prefix = utils.getLinePrefix(offset);
+ }
+
+ var parameters = debugFillProperties.parameters.parameters;
+ var propertiesBuilderName;
+ for (var parameter in parameters) {
+ if (parameter is SimpleFormalParameter) {
+ final type = parameter.type;
+ if (type is TypeName) {
+ if (type.name.name == 'DiagnosticPropertiesBuilder') {
+ propertiesBuilderName = parameter.identifier.name;
+ break;
+ }
+ }
+ }
+ }
+ if (propertiesBuilderName == null) {
+ return null;
+ }
+
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(utils.getLineNext(offset),
+ (DartEditBuilder builder) {
+ builder.write(
+ "$prefix$propertiesBuilderName.add($constructorInvocation('${name.name}', ${name.name}));$eol");
+ });
+ });
+ return changeBuilder;
+ }
+ }
+
+ return null;
+ }
+
Future<ChangeBuilder>
createBuilder_addTypeAnnotation_DeclaredIdentifier() async {
DeclaredIdentifier declaredIdentifier =
@@ -860,46 +963,6 @@
return changeBuilder;
}
- Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
- NamedExpression childProp = flutter.findNamedExpression(node, 'child');
- if (childProp == null) {
- childProp = flutter.findNamedExpression(node, 'children');
- }
- if (childProp == null) {
- return null;
- }
-
- var parent = childProp.parent?.parent;
- if (parent is! InstanceCreationExpression ||
- !flutter.isWidgetCreation(parent)) {
- return null;
- }
-
- InstanceCreationExpression creationExpression = parent;
- var args = creationExpression.argumentList;
-
- var last = args.arguments.last;
- if (last == childProp) {
- // Already sorted.
- return null;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var start = childProp.beginToken.previous.end;
- var end = childProp.endToken.next.end;
- var childRange = range.startOffsetEndOffset(start, end);
-
- var childText = utils.getRangeText(childRange);
- builder.addSimpleReplacement(childRange, '');
- builder.addSimpleInsertion(last.end + 1, childText);
-
- changeBuilder.setSelection(new Position(file, last.end + 1));
- });
-
- return changeBuilder;
- }
-
/// todo (pq): unify with similar behavior in fix.
Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
VariableDeclarationList declarationList =
@@ -945,6 +1008,46 @@
return changeBuilder;
}
+ Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
+ NamedExpression childProp = flutter.findNamedExpression(node, 'child');
+ if (childProp == null) {
+ childProp = flutter.findNamedExpression(node, 'children');
+ }
+ if (childProp == null) {
+ return null;
+ }
+
+ var parent = childProp.parent?.parent;
+ if (parent is! InstanceCreationExpression ||
+ !flutter.isWidgetCreation(parent)) {
+ return null;
+ }
+
+ InstanceCreationExpression creationExpression = parent;
+ var args = creationExpression.argumentList;
+
+ var last = args.arguments.last;
+ if (last == childProp) {
+ // Already sorted.
+ return null;
+ }
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var start = childProp.beginToken.previous.end;
+ var end = childProp.endToken.next.end;
+ var childRange = range.startOffsetEndOffset(start, end);
+
+ var childText = utils.getRangeText(childRange);
+ builder.addSimpleReplacement(childRange, '');
+ builder.addSimpleInsertion(last.end + 1, childText);
+
+ changeBuilder.setSelection(new Position(file, last.end + 1));
+ });
+
+ return changeBuilder;
+ }
+
@protected
Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
Future<ChangeBuilder> doStatement(DoStatement node) async {
@@ -1105,6 +1208,11 @@
return null;
}
+ bool isEnum(DartType type) {
+ final element = type.element;
+ return element is ClassElement && element.isEnum;
+ }
+
@protected
bool setupCompute() {
final locator = NodeLocator(selectionOffset, selectionEnd);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b2bc9a3..6a005f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -142,6 +142,10 @@
const FixKind('ADD_CONST', 50, "Add 'const' modifier");
static const ADD_CURLY_BRACES =
const FixKind('ADD_CURLY_BRACES', 50, "Add curly braces");
+ static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = const FixKind(
+ 'ADD_DIAGNOSTIC_PROPERTY_REFERENCE',
+ 50,
+ "Add a debug reference to this property");
static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
static const ADD_MISSING_ENUM_CASE_CLAUSES = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 7dff396..801408f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -628,6 +628,9 @@
if (name == LintNames.curly_braces_in_flow_control_structures) {
await _addFix_addCurlyBraces();
}
+ if (name == LintNames.diagnostic_describe_all_properties) {
+ await _addFix_addDiagnosticPropertyReference();
+ }
if (name == LintNames.empty_catches) {
await _addFix_removeEmptyCatch();
}
@@ -781,6 +784,12 @@
_addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
}
+ Future<void> _addFix_addDiagnosticPropertyReference() async {
+ final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
+ _addFixFromBuilder(
+ changeBuilder, DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
+ }
+
Future<void> _addFix_addExplicitCast() async {
if (coveredNode is! Expression) {
return;
@@ -3525,6 +3534,47 @@
}
}
+ Future<void> _addFix_removeUnusedElement() async {
+ final sourceRanges = <SourceRange>[];
+ final referencedNode = node.parent;
+ if (referencedNode is ClassDeclaration ||
+ referencedNode is EnumDeclaration ||
+ referencedNode is FunctionDeclaration ||
+ referencedNode is FunctionTypeAlias ||
+ referencedNode is MethodDeclaration ||
+ referencedNode is VariableDeclaration) {
+ final element = referencedNode is Declaration
+ ? referencedNode.declaredElement
+ : (referencedNode as NamedCompilationUnitMember).declaredElement;
+ final references = _findAllReferences(unit, element);
+ // todo (pq): consider filtering for references that are limited to within the class.
+ if (references.length == 1) {
+ var sourceRange;
+ if (referencedNode is VariableDeclaration) {
+ VariableDeclarationList parent = referencedNode.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, node);
+ }
+ } else {
+ sourceRange = utils.getLinesRange(range.node(referencedNode));
+ }
+ sourceRanges.add(sourceRange);
+ }
+ }
+
+ if (sourceRanges.isNotEmpty) {
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
+ }
+ }
+
Future<void> _addFix_removeUnusedField() async {
final declaration = node.parent;
if (declaration is! VariableDeclaration) {
@@ -3588,47 +3638,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_FIELD);
}
- Future<void> _addFix_removeUnusedElement() async {
- final sourceRanges = <SourceRange>[];
- final referencedNode = node.parent;
- if (referencedNode is ClassDeclaration ||
- referencedNode is EnumDeclaration ||
- referencedNode is FunctionDeclaration ||
- referencedNode is FunctionTypeAlias ||
- referencedNode is MethodDeclaration ||
- referencedNode is VariableDeclaration) {
- final element = referencedNode is Declaration
- ? referencedNode.declaredElement
- : (referencedNode as NamedCompilationUnitMember).declaredElement;
- final references = _findAllReferences(unit, element);
- // todo (pq): consider filtering for references that are limited to within the class.
- if (references.length == 1) {
- var sourceRange;
- if (referencedNode is VariableDeclaration) {
- VariableDeclarationList parent = referencedNode.parent;
- if (parent.variables.length == 1) {
- sourceRange = utils.getLinesRange(range.node(parent.parent));
- } else {
- sourceRange = range.nodeInList(parent.variables, node);
- }
- } else {
- sourceRange = utils.getLinesRange(range.node(referencedNode));
- }
- sourceRanges.add(sourceRange);
- }
- }
-
- if (sourceRanges.isNotEmpty) {
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- for (var sourceRange in sourceRanges) {
- builder.addDeletion(sourceRange);
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
- }
- }
-
Future<void> _addFix_removeUnusedImport() async {
// prepare ImportDirective
ImportDirective importDirective =
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index b3ee6f1..fbd3a46 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -20,6 +20,8 @@
static const String await_only_futures = 'await_only_futures';
static const String curly_braces_in_flow_control_structures =
'curly_braces_in_flow_control_structures';
+ static const String diagnostic_describe_all_properties =
+ 'diagnostic_describe_all_properties';
static const String empty_catches = 'empty_catches';
static const String empty_constructor_bodies = 'empty_constructor_bodies';
static const String empty_statements = 'empty_statements';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 3feab8b..ba6c8a3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -381,7 +381,7 @@
for (var invocation in collector.invocations) {
List<Expression> arguments = invocation.argumentList.arguments;
builder.addReplacement(range.node(invocation), (builder) {
- builder.write('new $name(');
+ builder.write('$name(');
// Insert field references (as named arguments).
// Ensure that invocation arguments are named.
@@ -545,7 +545,7 @@
/// Write instantiation of the new widget class.
void _writeWidgetInstantiation(DartEditBuilder builder) {
- builder.write('new $name(');
+ builder.write('$name(');
for (var parameter in _parameters) {
if (parameter != _parameters.first) {
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 7865f34..7056d15 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
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -21,61 +22,73 @@
/// library.
// TODO(srawlins): Add tests for navigation links, which use multiple
// libraries.
- String renderLibrary(LibraryInfo libraryInfo) {
- MigrationInfo migrationInfo =
- MigrationInfo([libraryInfo], resourceProvider.pathContext, '/project');
- return InstrumentationRenderer(libraryInfo, migrationInfo).render();
+ List<String> renderLibrary(LibraryInfo libraryInfo) {
+ String packageRoot = resourceProvider.convertPath('/package');
+ String outputDir = resourceProvider.convertPath('/output');
+ MigrationInfo migrationInfo = MigrationInfo(
+ libraryInfo.units, resourceProvider.pathContext, packageRoot);
+ List<String> contents = [];
+ for (UnitInfo unitInfo in libraryInfo.units) {
+ contents.add(InstrumentationRenderer(unitInfo, migrationInfo,
+ PathMapper(resourceProvider, outputDir, packageRoot))
+ .render());
+ }
+ return contents;
}
test_outputContainsEachPath() async {
LibraryInfo info = LibraryInfo([
- unit('/lib/a.dart', 'int? a = null;',
+ unit('/package/lib/a.dart', 'int? a = null;',
regions: [RegionInfo(3, 1, 'null was assigned', [])]),
- unit('/lib/part1.dart', 'int? b = null;',
+ unit('/package/lib/part1.dart', 'int? b = null;',
regions: [RegionInfo(3, 1, 'null was assigned', [])]),
- unit('/lib/part2.dart', 'int? c = null;',
+ unit('/package/lib/part2.dart', 'int? c = null;',
regions: [RegionInfo(3, 1, 'null was assigned', [])]),
]);
- String output = renderLibrary(info);
- expect(output, contains('<h2>/lib/a.dart</h2>'));
- expect(output, contains('<h2>/lib/part1.dart</h2>'));
- expect(output, contains('<h2>/lib/part2.dart</h2>'));
+ List<String> contents = renderLibrary(info);
+ expect(contents[0], contains(resourceProvider.convertPath('lib/a.dart')));
+ expect(
+ contents[1], contains(resourceProvider.convertPath('lib/part1.dart')));
+ expect(
+ contents[2], contains(resourceProvider.convertPath('lib/part2.dart')));
}
test_outputContainsEscapedHtml() async {
LibraryInfo info = LibraryInfo([
- unit('/lib/a.dart', 'List<String>? a = null;',
+ unit('/package/lib/a.dart', 'List<String>? a = null;',
regions: [RegionInfo(12, 1, 'null was assigned', [])]),
]);
- String output = renderLibrary(info);
+ String output = renderLibrary(info)[0];
expect(
output,
contains('List<String><span class="region">?'
- '<span class="tooltip">null was assigned</span></span> a = null;'));
+ '<span class="tooltip">null was assigned<ul></ul></span></span> '
+ 'a = null;'));
}
test_outputContainsEscapedHtml_ampersand() async {
LibraryInfo info = LibraryInfo([
- unit('/lib/a.dart', 'bool a = true && false;', regions: []),
+ unit('/package/lib/a.dart', 'bool a = true && false;', regions: []),
]);
- String output = renderLibrary(info);
+ String output = renderLibrary(info)[0];
expect(output, contains('bool a = true && false;'));
}
test_outputContainsModifiedAndUnmodifiedRegions() async {
LibraryInfo info = LibraryInfo([
- unit('/lib/a.dart', 'int? a = null;',
+ unit('/package/lib/a.dart', 'int? a = null;',
regions: [RegionInfo(3, 1, 'null was assigned', [])]),
]);
- String output = renderLibrary(info);
+ String output = renderLibrary(info)[0];
expect(
output,
contains('int<span class="region">?'
- '<span class="tooltip">null was assigned</span></span> a = null;'));
+ '<span class="tooltip">null was assigned<ul></ul></span></span> '
+ 'a = null;'));
}
UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
- return UnitInfo(path)
+ return UnitInfo(resourceProvider.convertPath(path))
..content = content
..regions.addAll(regions);
}
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
index 40e2ff6..799c69e 100644
--- a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
@@ -15,6 +15,9 @@
@reflectiveTest
class DiagnosticTest extends AbstractLspAnalysisServerIntegrationTest {
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_initialAnalysis() async {
newFile(mainFilePath, content: 'String a = 1;');
@@ -30,6 +33,9 @@
expect(diagnostic.range.end.character, equals(12));
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_lints() async {
newFile(mainFilePath, content: '''main() async => await 1;''');
newFile(analysisOptionsPath, content: '''
diff --git a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
index 8d364dc..91f75bc 100644
--- a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
@@ -17,6 +17,9 @@
@reflectiveTest
class InitializationTest extends AbstractLspAnalysisServerIntegrationTest {
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_initialize_invalidParams() async {
final params = {'processId': 'invalid'};
final request = new RequestMessage(
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index e1eeec2..23317b4 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -144,11 +144,24 @@
String dartBinary = Platform.executable;
- // TODO(dantup): The other servers integration tests can run with a snapshot
- // which is much faster - we may wish to investigate doing the same here.
- final rootDir =
- findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
- final serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+ final bool useSnapshot = true;
+ String serverPath;
+
+ if (useSnapshot) {
+ // Look for snapshots/analysis_server.dart.snapshot.
+ serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+ 'snapshots', 'analysis_server.dart.snapshot'));
+
+ if (!FileSystemEntity.isFileSync(serverPath)) {
+ // Look for dart-sdk/bin/snapshots/analysis_server.dart.snapshot.
+ serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+ 'dart-sdk', 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
+ }
+ } else {
+ final rootDir =
+ findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+ serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+ }
final arguments = [serverPath, '--lsp', '--suppress-analytics'];
_process = await Process.start(dartBinary, arguments);
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 0b73ad4..fd7e279 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -18,6 +18,9 @@
@reflectiveTest
class ServerTest extends AbstractLspAnalysisServerIntegrationTest {
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_diagnosticServer() async {
await initialize();
@@ -38,6 +41,9 @@
expect(responseBody, contains('<title>Analysis Server</title>'));
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_exit_inintializedWithShutdown() async {
await initialize();
await sendShutdown();
@@ -53,6 +59,9 @@
expect(exitCode, equals(0));
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_exit_initializedWithoutShutdown() async {
// Send a request that we can wait for, to ensure the server is fully ready
// before we send exit. Otherwise the exit notification won't be handled for
@@ -70,6 +79,9 @@
expect(exitCode, equals(1));
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_exit_uninintializedWithShutdown() async {
await sendShutdown();
sendExit();
@@ -84,6 +96,9 @@
expect(exitCode, equals(0));
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_exit_uninitializedWithoutShutdown() async {
// This tests the same as test_exit_withoutShutdown but without sending
// initialize. It can't be as strict with the timeout as the server may take
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index 55d5140..6a1cd63 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -112,7 +112,7 @@
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
- new NewWidget(),
+ NewWidget(),
new Text('CCC'),
new Text('DDD'),
],
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 648b7ed..7de98f7 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -208,9 +208,23 @@
});
// Initialize with no dynamic registrations advertised.
- await initialize();
+ final initResponse = await initialize();
await pumpEventQueue();
+ // When dynamic registration is not supported, we will always statically
+ // request text document open/close and incremental updates.
+ InitializeResult initResult = initResponse.result;
+ expect(initResult.capabilities, isNotNull);
+ expect(initResult.capabilities.textDocumentSync, isNotNull);
+ initResult.capabilities.textDocumentSync.map(
+ (options) {
+ expect(options.openClose, isTrue);
+ expect(options.change, equals(TextDocumentSyncKind.Incremental));
+ },
+ (_) =>
+ throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+ );
+
expect(didGetRegisterCapabilityRequest, isFalse);
}
@@ -237,7 +251,8 @@
// for ex including analysis_options.yaml in text synchronization but not
// for hovers.
List<Registration> registrations;
- await handleExpectedRequest<void, RegistrationParams, void>(
+ final initResponse =
+ await handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
Method.client_registerCapability,
() => initialize(
// Support dynamic registration for both text sync + hovers.
@@ -248,6 +263,21 @@
registrations = registrationParams.registrations,
);
+ // Because we support dynamic registration for synchronisation, we won't send
+ // static registrations for them.
+ // https://github.com/dart-lang/sdk/issues/38490
+ InitializeResult initResult = initResponse.result;
+ expect(initResult.capabilities, isNotNull);
+ expect(initResult.capabilities.textDocumentSync, isNotNull);
+ initResult.capabilities.textDocumentSync.map(
+ (options) {
+ expect(options.openClose, isFalse);
+ expect(options.change, equals(TextDocumentSyncKind.None));
+ },
+ (_) =>
+ throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+ );
+
// Should container Hover, DidOpen, DidClose, DidChange.
expect(registrations, hasLength(4));
final hover =
diff --git a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
index 580a076..1ed98d3 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
@@ -121,7 +121,7 @@
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
- new Test(),
+ Test(),
new Text('CCC'),
new Text('DDD'),
],
@@ -173,7 +173,7 @@
Widget foo() {
return new Row(
children: <Widget>[
- new Test(),
+ Test(),
new Text('BBB'),
],
);
@@ -214,7 +214,7 @@
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return new Test();
+ return Test();
}
}
@@ -249,7 +249,7 @@
import 'package:flutter/material.dart';
Widget main() {
- return new Test();
+ return Test();
}
class Test extends StatelessWidget {
@@ -301,7 +301,7 @@
Widget main() {
return new Row(
children: <Widget>[
- new Test(),
+ Test(),
new Text('BBB'),
],
);
@@ -409,7 +409,7 @@
@override
Widget build(BuildContext context) {
- return new Test(c: c);
+ return Test(c: c);
}
}
@@ -462,7 +462,7 @@
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return new Test();
+ return Test();
}
}
@@ -524,8 +524,8 @@
int bar = 1;
return new Row(
children: <Widget>[
- new Test(foo: foo, p1: 'aaa', p2: bar),
- new Test(foo: foo, p1: 'bbb', p2: 2),
+ Test(foo: foo, p1: 'aaa', p2: bar),
+ Test(foo: foo, p1: 'bbb', p2: 2),
],
);
}
@@ -596,8 +596,8 @@
int bar = 1;
return new Row(
children: <Widget>[
- new Test(foo: foo, p1: 'aaa', p2: bar),
- new Test(foo: foo, p1: 'bbb', p2: 2),
+ Test(foo: foo, p1: 'aaa', p2: bar),
+ Test(foo: foo, p1: 'bbb', p2: 2),
],
);
}
@@ -651,7 +651,7 @@
@override
Widget build(BuildContext context) {
- return new Test(field: field);
+ return Test(field: field);
}
}
@@ -703,7 +703,7 @@
@override
Widget build(BuildContext context) {
- return new Test(c: c);
+ return Test(c: c);
}
}
@@ -747,7 +747,7 @@
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return new Test();
+ return Test();
}
}
@@ -853,7 +853,7 @@
@override
Widget build(BuildContext context) {
- return new Test(c: c);
+ return Test(c: c);
}
}
@@ -919,7 +919,7 @@
@override
Widget build(BuildContext context) {
String local;
- return new Test(local: local);
+ return Test(local: local);
}
}
@@ -987,7 +987,7 @@
@override
Widget build(BuildContext context) {
- return new Test(field: _field);
+ return Test(field: _field);
}
}
@@ -1033,7 +1033,7 @@
@override
Widget build(BuildContext context) {
- return new Test(field: field, field2: _field);
+ return Test(field: field, field2: _field);
}
}
@@ -1086,7 +1086,7 @@
@override
Widget build(BuildContext context) {
String local;
- return new Test(field: field, local: local);
+ return Test(field: field, local: local);
}
}
@@ -1157,7 +1157,7 @@
var index = 0;
var a = 'a $index';
// start
- return new Test(index: index, a: a);
+ return Test(index: index, a: a);
// end
}
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
index 408a7a7..a2b0dcc 100644
--- 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
@@ -136,11 +136,11 @@
Folder outputDir = getFolder('/outputDir');
await performFix(included: [projectPath], outputDir: outputDir.path);
expect(outputDir.exists, true);
- expect(getFile('/outputDir/bin/bin.html').exists, isTrue);
- expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
- expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
- expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
- expect(getFile('/outputDir/test/test.html').exists, isTrue);
+ expect(getFile('/outputDir/project/bin/bin.html').exists, isTrue);
+ expect(getFile('/outputDir/project/lib/lib1.html').exists, isTrue);
+ expect(getFile('/outputDir/project/lib/lib2.html').exists, isTrue);
+ expect(getFile('/outputDir/project/lib/src/lib3.html').exists, isTrue);
+ expect(getFile('/outputDir/project/test/test.html').exists, isTrue);
}
test_outputDirContainsFilesRootedInASubdirectory() async {
@@ -150,9 +150,9 @@
included: [context.join(projectPath, 'lib')],
outputDir: outputDir.path);
expect(outputDir.exists, true);
- expect(getFile('/outputDir/lib1.html').exists, isTrue);
- expect(getFile('/outputDir/lib2.html').exists, isTrue);
- expect(getFile('/outputDir/src/lib3.html').exists, isTrue);
+ expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
+ expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
+ expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
}
test_outputDirContainsFilesRootedInParentOfSingleFile() async {
@@ -162,6 +162,11 @@
included: [context.join(projectPath, 'lib', 'lib2.dart')],
outputDir: outputDir.path);
expect(outputDir.exists, true);
- expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
+ expect(
+ outputDir
+ .getChildAssumingFolder('lib')
+ .getChildAssumingFile('lib2.html')
+ .exists,
+ isTrue);
}
}
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
index ca0162f..d349e0d 100644
--- 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
@@ -25,7 +25,7 @@
class InfoBuilderTest extends AbstractAnalysisTest {
/// The information produced by the InfoBuilder, or `null` if [buildInfo] has
/// not yet completed.
- List<LibraryInfo> infos;
+ List<UnitInfo> infos;
/// Use the InfoBuilder to build information. The information will be stored
/// in [infos].
@@ -53,7 +53,7 @@
infos = await builder.explainMigration();
}
- test_parameter_nullableFromInvocation() async {
+ test_parameter_nullable_fromInvocation() async {
addTestFile('''
void f(String s) {}
void g() {
@@ -62,9 +62,7 @@
''');
await buildInfo();
expect(infos, hasLength(1));
- List<UnitInfo> units = infos[0].units;
- expect(units, hasLength(1));
- UnitInfo unit = units[0];
+ UnitInfo unit = infos[0];
expect(unit.path, testFile);
expect(unit.content, '''
void f(String? s) {}
@@ -77,5 +75,37 @@
RegionInfo region = regions[0];
expect(region.offset, 13);
expect(region.length, 1);
+ List<RegionDetail> details = region.details;
+ expect(details, hasLength(1));
+ }
+
+ test_parameter_nullable_fromOverriden() async {
+ addTestFile('''
+class A {
+ void m(p) {}
+}
+class B extends A {
+ void m(Object p) {}
+}
+''');
+ await buildInfo();
+ expect(infos, hasLength(1));
+ UnitInfo unit = infos[0];
+ expect(unit.path, testFile);
+ expect(unit.content, '''
+class A {
+ void m(p) {}
+}
+class B extends A {
+ void m(Object? p) {}
+}
+''');
+ List<RegionInfo> regions = unit.regions;
+ expect(regions, hasLength(1));
+ RegionInfo region = regions[0];
+ expect(region.offset, 62);
+ expect(region.length, 1);
+ List<RegionDetail> details = region.details;
+ expect(details, hasLength(1));
}
}
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index df7d05f..384cafc 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -202,6 +202,9 @@
notificationManager, InstrumentationService.NULL_SERVICE);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_addPluginToContextRoot() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -233,6 +236,9 @@
// pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_broadcastRequest_many() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -259,6 +265,9 @@
pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_broadcastRequest_many_noContextRoot() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -283,6 +292,9 @@
pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_broadcastWatchEvent() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -306,6 +318,9 @@
pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_pluginsForContextRoot_multiple() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -333,6 +348,9 @@
pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_pluginsForContextRoot_one() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -349,6 +367,9 @@
pkg1Dir.deleteSync(recursive: true);
}
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_removedContextRoot() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -364,6 +385,9 @@
}
@TestTimeout(const Timeout.factor(4))
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_restartPlugins() async {
io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
String pkg1Path = pkg1Dir.resolveSymbolicLinksSync();
@@ -514,6 +538,9 @@
@reflectiveTest
class PluginSessionFromDiskTest extends PluginTestSupport {
+ @SkippedTest(
+ reason: 'flaky timeouts',
+ issue: 'https://github.com/dart-lang/sdk/issues/38629')
test_start_notRunning() async {
await withPlugin(test: (String pluginPath) async {
String packagesPath = path.join(pluginPath, '.packages');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
new file mode 100644
index 0000000..13f5ab3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
@@ -0,0 +1,214 @@
+// 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/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddDiagnosticPropertyReferenceTest);
+ });
+}
+
+@reflectiveTest
+class AddDiagnosticPropertyReferenceTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+ @override
+ String get lintCode => LintNames.diagnostic_describe_all_properties;
+
+ test_boolField_debugFillProperties() async {
+ await resolveTestUnit('''
+class Absorber extends Widget {
+ bool get absorbing => _absorbing;
+ bool _absorbing;
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+ }
+}
+''');
+ await assertHasFix('''
+class Absorber extends Widget {
+ bool get absorbing => _absorbing;
+ bool _absorbing;
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+ properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+ }
+}
+''');
+ }
+
+ test_boolField_debugFillProperties_empty() async {
+ await resolveTestUnit('''
+class Absorber extends Widget {
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ }
+}
+''');
+ await assertHasFix('''
+class Absorber extends Widget {
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+ }
+}
+''');
+ }
+
+ test_boolField_debugFillProperties_empty_customParamName() async {
+ await resolveTestUnit('''
+class Absorber extends Widget {
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder props) {
+ }
+}
+''');
+ await assertHasFix('''
+class Absorber extends Widget {
+ bool /*LINT*/ignoringSemantics;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder props) {
+ props.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+ }
+}
+''');
+ }
+
+ test_boolGetter_debugFillProperties() async {
+ await resolveTestUnit('''
+class Absorber extends Widget {
+ bool get /*LINT*/absorbing => _absorbing;
+ bool _absorbing;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class Absorber extends Widget {
+ bool get /*LINT*/absorbing => _absorbing;
+ bool _absorbing;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+ }
+}
+''');
+ }
+
+ test_doubleField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ double /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ double /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DoubleProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_enumField_debugFillProperties() async {
+ await resolveTestUnit('''
+enum foo {bar}
+class A extends Widget {
+ foo /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+enum foo {bar}
+class A extends Widget {
+ foo /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(EnumProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_intField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ int /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ int /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(IntProperty('field', field));
+ }
+}
+''');
+ }
+
+ test_stringField_debugFillProperties() async {
+ await resolveTestUnit('''
+class A extends Widget {
+ String /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ }
+}
+''');
+ await assertHasFix('''
+class A extends Widget {
+ String /*LINT*/field;
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(StringProperty('field', field));
+ }
+}
+''');
+ }
+
+ // todo (pq): tests for no debugFillProperties method
+ // todo (pq): consider a test for a body w/ no CR
+ // todo (pq): support for ColorProperty -- for Color
+ // todo (pq): support for IterableProperty -- any iterable
+ // todo (pq): support for TransformProperty -- Matrix4
+ // todo (pq): support for DiagnosticsProperty for any T that doesn't match one of the other cases
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 3509418..3c6ba74 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -8,6 +8,8 @@
import 'add_await_test.dart' as add_await;
import 'add_const_test.dart' as add_const;
import 'add_curly_braces_test.dart' as add_curly_braces;
+import 'add_diagnostic_property_reference_test.dart'
+ as add_diagnostic_property_reference;
import 'add_explicit_cast_test.dart' as add_explicit_cast;
import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
import 'add_missing_enum_case_clauses_test.dart'
@@ -140,6 +142,7 @@
add_await.main();
add_const.main();
add_curly_braces.main();
+ add_diagnostic_property_reference.main();
add_explicit_cast.main();
add_field_formal_parameters.main();
add_missing_enum_case_clauses.main();
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 3fa0592..59199b3 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -10,14 +10,10 @@
# 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
diff --git a/pkg/analyzer/lib/dart/analysis/context_locator.dart b/pkg/analyzer/lib/dart/analysis/context_locator.dart
index d2c4cd3..2211439 100644
--- a/pkg/analyzer/lib/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_locator.dart
@@ -39,9 +39,9 @@
List<AnalysisContext> locateContexts(
{@required List<String> includedPaths,
List<String> excludedPaths: const <String>[],
- String optionsFile: null,
- String packagesFile: null,
- String sdkPath: null});
+ String optionsFile,
+ String packagesFile,
+ String sdkPath});
/// Return a list of the context roots that should be used to analyze the
/// files that are included by the list of [includedPaths] and not excluded by
@@ -57,7 +57,7 @@
/// found by looking in the directories containing the context roots.
List<ContextRoot> locateRoots(
{@required List<String> includedPaths,
- List<String> excludedPaths: null,
- String optionsFile: null,
- String packagesFile: null});
+ List<String> excludedPaths,
+ String optionsFile,
+ String packagesFile});
}
diff --git a/pkg/analyzer/lib/exception/exception.dart b/pkg/analyzer/lib/exception/exception.dart
index e475c04..73b1a5d 100644
--- a/pkg/analyzer/lib/exception/exception.dart
+++ b/pkg/analyzer/lib/exception/exception.dart
@@ -21,7 +21,7 @@
* Initialize a newly created exception to have the given [message] and
* [cause].
*/
- AnalysisException([this.message = 'Exception', this.cause = null]);
+ AnalysisException([this.message = 'Exception', this.cause]);
String toString() {
StringBuffer buffer = new StringBuffer();
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index 5d3e616..2566e22 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -41,7 +41,7 @@
/// The given [root] directory will be searched first. If no file is found and
/// if [crawlUp] is `true`, then enclosing directories will be searched.
File getOptionsFile(Folder root, {bool crawlUp: false}) {
- Resource resource = null;
+ Resource resource;
for (Folder folder = root; folder != null; folder = folder.parent) {
resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
if (resource.exists) {
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 4a58ff8..a1840b0 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -78,7 +78,7 @@
* create their own drivers with the same tools, in theory. Here as a stopgap
* until the official plugin API is complete
*/
- static Function onCreateAnalysisDriver = null;
+ static Function onCreateAnalysisDriver;
/**
* The [ResourceProvider] by which paths are converted into [Resource]s.
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 71abce1..07a26ee 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -251,7 +251,7 @@
// Check .packages and update target and actual URIs as appropriate.
if (_packages != null && containedUri.scheme == 'package') {
- Uri packageUri = null;
+ Uri packageUri;
try {
packageUri =
_packages.resolve(containedUri, notFound: (Uri packageUri) => null);
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 52a6a24..1f6826a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -76,9 +76,9 @@
List<AnalysisContext> locateContexts(
{@required List<String> includedPaths,
List<String> excludedPaths: const <String>[],
- String optionsFile: null,
- String packagesFile: null,
- String sdkPath: null}) {
+ String optionsFile,
+ String packagesFile,
+ String sdkPath}) {
List<ContextRoot> roots = locateRoots(
includedPaths: includedPaths,
excludedPaths: excludedPaths,
@@ -120,9 +120,9 @@
@override
List<ContextRoot> locateRoots(
{@required List<String> includedPaths,
- List<String> excludedPaths: null,
- String optionsFile: null,
- String packagesFile: null}) {
+ List<String> excludedPaths,
+ String optionsFile,
+ String packagesFile}) {
//
// Compute the list of folders and files that are to be included.
//
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index c71d4d3..f28a361 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,6 +95,11 @@
/// zero, we stop writing any new exception contexts in this process.
static int allowedNumberOfContextsToWrite = 10;
+ /// Whether summary2 should be used to resynthesize elements.
+ @Deprecated('Clients should assume summary2 is used. '
+ 'Summary1 support has been removed.')
+ static bool get useSummary2 => true;
+
/// The scheduler that schedules analysis work in this, and possibly other
/// analysis drivers.
final AnalysisDriverScheduler _scheduler;
@@ -1592,7 +1597,7 @@
}
void _reportException(String path, exception, StackTrace stackTrace) {
- String contextKey = null;
+ String contextKey;
if (exception is _ExceptionState) {
var state = exception as _ExceptionState;
exception = state.exception;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 06b9e65..d4c2171 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -27,7 +27,7 @@
List<bool> _buildExperimentalFlagsArray() => <bool>[
true, // constant-update-2018
true, // control-flow-collections
- IsEnabledByDefault.extension_methods,
+ true, // extension-methods
IsEnabledByDefault.non_nullable,
true, // set-literals
true, // spread-collections
@@ -95,7 +95,8 @@
EnableString.extension_methods,
IsEnabledByDefault.extension_methods,
IsExpired.extension_methods,
- 'Extension Methods');
+ 'Extension Methods',
+ firstSupportedVersion: '2.6.0');
static const non_nullable = const ExperimentalFeature(
3,
@@ -160,7 +161,7 @@
static const bool control_flow_collections = true;
/// Default state of the experiment "extension-methods"
- static const bool extension_methods = false;
+ static const bool extension_methods = true;
/// Default state of the experiment "non-nullable"
static const bool non_nullable = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 80d34b3..cfb2a93 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -507,7 +507,7 @@
ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
- LibraryIdentifier libraryNameNode = null;
+ LibraryIdentifier libraryNameNode;
var seenPartSources = new Set<Source>();
var directivesToResolve = <Directive>[];
int partIndex = 0;
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d38a651..dc4cc41 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -876,7 +876,7 @@
}
// Create locations for every usage of the element.
List<SearchResult> results = <SearchResult>[];
- CompilationUnitElement enclosingUnitElement = null;
+ CompilationUnitElement enclosingUnitElement;
for (;
i < index.usedElements.length && index.usedElements[i] == elementId;
i++) {
@@ -956,7 +956,7 @@
// Create results for every usage of the name.
List<SearchResult> results = <SearchResult>[];
- CompilationUnitElement enclosingUnitElement = null;
+ CompilationUnitElement enclosingUnitElement;
for (; i < index.usedNames.length && index.usedNames[i] == nameId; i++) {
IndexRelationKind relationKind = index.usedNameKinds[i];
SearchResultKind resultKind = relationToResultKind[relationKind];
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 9dd4e72..4e5e5ac 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -716,7 +716,7 @@
/// representing the parameter to which the value of the right operand will be
/// bound. Otherwise, return `null`.
ParameterElement get _staticParameterElementForRightHandSide {
- ExecutableElement executableElement = null;
+ ExecutableElement executableElement;
if (staticElement != null) {
executableElement = staticElement;
} else {
@@ -5938,7 +5938,7 @@
/// If this expression is both in a getter and setter context, the
/// [AuxiliaryElements] will be set to hold onto the static element from the
/// getter context.
- AuxiliaryElements auxiliaryElements = null;
+ AuxiliaryElements auxiliaryElements;
/// Initialize a newly created index expression.
IndexExpressionImpl.forCascade(
@@ -8921,7 +8921,7 @@
/// If this expression is both in a getter and setter context, the
/// [AuxiliaryElements] will be set to hold onto the static element from the
/// getter context.
- AuxiliaryElements auxiliaryElements = null;
+ AuxiliaryElements auxiliaryElements;
@override
List<DartType> tearOffTypeArgumentTypes;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 6efad5a..67c908d 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -6189,7 +6189,7 @@
@override
void visitFormalParameterList(FormalParameterList node) {
- String groupEnd = null;
+ String groupEnd;
_writer.print('(');
NodeList<FormalParameter> parameters = node.parameters;
int size = parameters.length;
@@ -7496,7 +7496,7 @@
@override
void visitFormalParameterList(FormalParameterList node) {
- String groupEnd = null;
+ String groupEnd;
sink.write('(');
NodeList<FormalParameter> parameters = node.parameters;
int size = parameters.length;
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 9f37e6b..0d81332 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -231,7 +231,7 @@
// type.
NodeList<SwitchMember> switchMembers = node.members;
bool foundError = false;
- DartType firstType = null;
+ DartType firstType;
for (SwitchMember switchMember in switchMembers) {
if (switchMember is SwitchCase) {
Expression expression = switchMember.expression;
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 0f2f144..42f7ab6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -585,8 +585,8 @@
while (baseParameter is ParameterMember) {
baseParameter = (baseParameter as ParameterMember).baseElement;
}
- DartObjectImpl argumentValue = null;
- AstNode errorTarget = null;
+ DartObjectImpl argumentValue;
+ AstNode errorTarget;
if (baseParameter.isNamed) {
argumentValue = namedValues[baseParameter.name];
errorTarget = namedNodes[baseParameter.name];
@@ -652,8 +652,8 @@
ConstantVisitor initializerVisitor = new ConstantVisitor(
this, externalErrorReporter,
lexicalEnvironment: parameterMap);
- String superName = null;
- NodeList<Expression> superArguments = null;
+ String superName;
+ NodeList<Expression> superArguments;
for (var i = 0; i < initializers.length; i++) {
var initializer = initializers[i];
if (initializer is ConstructorFieldInitializer) {
@@ -875,11 +875,7 @@
// fixed.
return true;
}
- // TODO(scheglov ) Switch to using this, but not now, dartbug.com/33441
- if (typeSystem.isSubtypeOf(objType, type)) {
- return true;
- }
- return objType.isSubtypeOf(type);
+ return typeSystem.isSubtypeOf(objType, type);
}
/// Determine whether the given string is a valid name for a public symbol
@@ -1018,7 +1014,7 @@
@override
DartObjectImpl visitAdjacentStrings(AdjacentStrings node) {
- DartObjectImpl result = null;
+ DartObjectImpl result;
for (StringLiteral string in node.strings) {
if (result == null) {
result = string.accept(this);
@@ -1432,7 +1428,7 @@
@override
DartObjectImpl visitStringInterpolation(StringInterpolation node) {
- DartObjectImpl result = null;
+ DartObjectImpl result;
bool first = true;
for (InterpolationElement element in node.elements) {
if (first) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 98921f2..c87f158 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1272,7 +1272,7 @@
/// application classes which have been visited on the way to reaching this
/// one (this is used to detect circularities).
List<ConstructorElement> _computeMixinAppConstructors(
- [List<ClassElementImpl> visitedClasses = null]) {
+ [List<ClassElementImpl> visitedClasses]) {
// First get the list of constructors of the superclass which need to be
// forwarded to this class.
Iterable<ConstructorElement> constructorsToForward;
@@ -1654,7 +1654,7 @@
/// A table mapping the offset of a directive to the annotations associated
/// with that directive, or `null` if none of the annotations in the
/// compilation unit have annotations.
- Map<int, List<ElementAnnotation>> annotationMap = null;
+ Map<int, List<ElementAnnotation>> annotationMap;
/// A list containing all of the top-level accessors (getters and setters)
/// contained in this compilation unit.
@@ -4766,7 +4766,7 @@
buffer.write('>');
}
buffer.write('(');
- String closing = null;
+ String closing;
ParameterKind kind = ParameterKind.REQUIRED;
int parameterCount = parameters.length;
for (int i = 0; i < parameterCount; i++) {
@@ -6965,7 +6965,7 @@
/// if not present. If _libraryCycle is set, then the _libraryCycle field
/// for all libraries reachable from this library in the import/export graph
/// is also set.
- List<LibraryElement> _libraryCycle = null;
+ List<LibraryElement> _libraryCycle;
/// A list containing all of the compilation units that are included in this
/// library using a `part` directive.
@@ -7434,7 +7434,7 @@
// Pop the elements, and share the component across all
// of the elements.
List<LibraryElement> component = <LibraryElement>[];
- LibraryElementImpl cur = null;
+ LibraryElementImpl cur;
do {
cur = stack.removeLast();
active.remove(cur);
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index b27a187..63238fc 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -344,7 +344,7 @@
List<Conflict> _findMostSpecificFromNamedCandidates(
Map<Name, FunctionType> map,
Map<Name, List<FunctionType>> namedCandidates) {
- List<Conflict> conflicts = null;
+ List<Conflict> conflicts;
for (var name in namedCandidates.keys) {
if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 1c9a60d..f457b8a 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -340,7 +340,7 @@
List<Conflict> _findMostSpecificFromNamedCandidates(
Map<Name, ExecutableElement> map,
Map<Name, List<ExecutableElement>> namedCandidates) {
- List<Conflict> conflicts = null;
+ List<Conflict> conflicts;
for (var name in namedCandidates.keys) {
if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 6d27b90..737047d 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -608,7 +608,7 @@
buffer.write('>');
}
buffer.write('(');
- String closing = null;
+ String closing;
ParameterKind kind = ParameterKind.REQUIRED;
int parameterCount = parameters.length;
for (int i = 0; i < parameterCount; i++) {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 68a0c7c..c1339c9 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1259,7 +1259,7 @@
/**
* The version of [element] for which members are cached.
*/
- int _versionOfCachedMembers = null;
+ int _versionOfCachedMembers;
/**
* Cached [ConstructorElement]s - members or raw elements.
@@ -2847,8 +2847,6 @@
* A concrete implementation of a [TypeParameterType].
*/
class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
- static bool _comparingBounds = false;
-
@override
final NullabilitySuffix nullabilitySuffix;
@@ -2874,20 +2872,10 @@
@override
bool operator ==(Object other) {
- if (other is TypeParameterTypeImpl && element == other.element) {
- if (_comparingBounds) {
- // If we're comparing bounds already, then we only need type variable
- // equality.
- return true;
- }
- _comparingBounds = true;
- try {
- return bound == other.bound;
- } finally {
- _comparingBounds = false;
- }
+ if (identical(other, this)) {
+ return true;
}
- return false;
+ return other is TypeParameterTypeImpl && other.element == element;
}
@override
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index cf5639a..756feb8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -4,13 +4,9 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -20,7 +16,6 @@
/// A visitor that will re-write an AST to support the optional `new` and
/// `const` feature.
class AstRewriteVisitor extends ScopedVisitor {
- final bool addConstKeyword;
final TypeSystem typeSystem;
/// Initialize a newly created visitor.
@@ -30,8 +25,7 @@
Source source,
TypeProvider typeProvider,
AnalysisErrorListener errorListener,
- {Scope nameScope,
- this.addConstKeyword: false})
+ {Scope nameScope})
: super(definingLibrary, source, typeProvider, errorListener,
nameScope: nameScope);
@@ -60,7 +54,7 @@
astFactory.constructorName(typeName, null, null);
InstanceCreationExpression instanceCreationExpression =
astFactory.instanceCreationExpression(
- _getKeyword(node), constructorName, node.argumentList);
+ null, constructorName, node.argumentList);
NodeReplacer.replace(node, instanceCreationExpression);
} else if (element is ExtensionElement) {
ExtensionOverride extensionOverride = astFactory.extensionOverride(
@@ -94,7 +88,7 @@
// TODO(scheglov) I think we should drop "typeArguments" below.
InstanceCreationExpression instanceCreationExpression =
astFactory.instanceCreationExpression(
- _getKeyword(node), constructorName, node.argumentList,
+ null, constructorName, node.argumentList,
typeArguments: typeArguments);
NodeReplacer.replace(node, instanceCreationExpression);
}
@@ -113,7 +107,7 @@
astFactory.constructorName(typeName, null, null);
InstanceCreationExpression instanceCreationExpression =
astFactory.instanceCreationExpression(
- _getKeyword(node), constructorName, node.argumentList);
+ null, constructorName, node.argumentList);
NodeReplacer.replace(node, instanceCreationExpression);
} else if (prefixedElement is ExtensionElement) {
PrefixedIdentifier extensionName =
@@ -147,49 +141,11 @@
astFactory.constructorName(typeName, node.operator, methodName);
InstanceCreationExpression instanceCreationExpression =
astFactory.instanceCreationExpression(
- _getKeyword(node), constructorName, node.argumentList);
+ null, constructorName, node.argumentList);
NodeReplacer.replace(node, instanceCreationExpression);
}
}
}
}
}
-
- /// Return the token that should be used in the [InstanceCreationExpression]
- /// that corresponds to the given invocation [node].
- Token _getKeyword(MethodInvocation node) {
- return addConstKeyword
- ? new KeywordToken(Keyword.CONST, node.offset)
- : null;
- }
-
- /// Return the type of the given class [element] after substituting any type
- /// arguments from the list of [typeArguments] for the class' type parameters.
- static InterfaceType getType(TypeSystem typeSystem, ClassElement element,
- TypeArgumentList typeArguments) {
- DartType type = element.type;
-
- List<TypeParameterElement> typeParameters = element.typeParameters;
- if (typeParameters.isEmpty) {
- return type;
- }
-
- if (typeArguments == null) {
- return typeSystem.instantiateToBounds(type);
- }
-
- List<DartType> argumentTypes;
- if (typeArguments.arguments.length == typeParameters.length) {
- argumentTypes = typeArguments.arguments
- .map((TypeAnnotation argument) => argument.type)
- .toList();
- } else {
- argumentTypes = List<DartType>.filled(
- typeParameters.length, DynamicTypeImpl.instance);
- }
- List<DartType> parameterTypes = typeParameters
- .map((TypeParameterElement parameter) => parameter.type)
- .toList();
- return type.substitute2(argumentTypes, parameterTypes);
- }
}
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 4ac8a57..56e6382 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -311,7 +311,7 @@
ClassElement classElement, SimpleIdentifier propertyName) {
// TODO(scheglov) Replace with class hierarchy.
String name = propertyName.name;
- Element element = null;
+ Element element;
if (propertyName.inSetterContext()) {
element = classElement.getSetter(name);
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index ef8de3a..9304c38 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -1035,7 +1035,7 @@
* A table mapping names that are defined in this scope to the element
* representing the thing declared with that name.
*/
- Map<String, Element> _definedNames = null;
+ Map<String, Element> _definedNames;
/**
* Return the scope in which this scope is lexically enclosed.
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 6bf0d08..b3432d7 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -616,8 +616,8 @@
*/
LibraryMap initialLibraryMap(bool useDart2jsPaths) {
List<String> searchedPaths = <String>[];
- var lastStackTrace = null;
- var lastException = null;
+ StackTrace lastStackTrace;
+ Object lastException;
for (File librariesFile in _libraryMapLocations) {
try {
String contents = librariesFile.readAsStringSync();
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 8ece3f2..ac9b421 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -189,7 +189,7 @@
_checkForMismatchedAccessorTypes(interface);
if (!classElement.isAbstract) {
- List<ExecutableElement> inheritedAbstract = null;
+ List<ExecutableElement> inheritedAbstract;
for (var name in interface.map.keys) {
if (!name.isAccessibleFor(libraryUri)) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index df889e0..5b76714 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1747,6 +1747,15 @@
// extensions. They are invalid and the parser has already reported an
// error at this point. In the future, we should include them in order
// to get navigation, search, etc.
+ pop(); // body
+ pop(); // initializers
+ pop(); // separator
+ pop(); // parameters
+ pop(); // typeParameters
+ pop(); // name
+ pop(); // returnType
+ pop(); // modifiers
+ pop(); // metadata
}
@override
@@ -3593,7 +3602,7 @@
/// Return the token that is lexically first.
Token get beginToken {
- Token firstToken = null;
+ Token firstToken;
for (Token token in [
abstractKeyword,
externalKeyword,
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index a8dfa2e..2813216 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -774,6 +774,6 @@
/// and [cause].
_ElementMismatchException(
CompilationUnitElement compilationUnit, Element element,
- [CaughtException cause = null])
+ [CaughtException cause])
: super('Element mismatch in $compilationUnit at $element', cause);
}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index fd7e626..17b73d5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,9 +19,7 @@
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';
@@ -711,7 +709,7 @@
[memberName, element.name]);
}
if (propertyName.inGetterContext()) {
- PropertyAccessorElement getter = result.getter;
+ ExecutableElement getter = result.getter;
if (getter == null) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -1101,6 +1099,16 @@
return _resolveTypeParameter(type);
}
+ InterfaceType _instantiateAnnotationClass(ClassElement element) {
+ return element.instantiate(
+ typeArguments: List.filled(
+ element.typeParameters.length,
+ _dynamicType,
+ ),
+ nullabilitySuffix: _resolver.noneOrStarSuffix,
+ );
+ }
+
/**
* Check for a generic method & apply type arguments if any were passed.
*/
@@ -1254,44 +1262,6 @@
_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;
@@ -1338,11 +1308,8 @@
}
// Class(args)
if (element1 is ClassElement) {
- constructor = _resolveAnnotationConstructor(
- element1,
- null,
- annotation.arguments,
- );
+ constructor = _instantiateAnnotationClass(element1)
+ .lookUpConstructor(null, _definingLibrary);
} else if (element1 == null) {
undefined = true;
}
@@ -1370,11 +1337,8 @@
}
// Class.constructor(args)
if (element1 is ClassElement) {
- constructor = _resolveAnnotationConstructor(
- element1,
- nameNode2.name,
- annotation.arguments,
- );
+ constructor = _instantiateAnnotationClass(element1)
+ .lookUpConstructor(nameNode2.name, _definingLibrary);
nameNode2.staticElement = constructor;
}
if (element1 == null && element2 == null) {
@@ -1399,11 +1363,8 @@
return;
}
// prefix.Class.constructor(args)
- constructor = _resolveAnnotationConstructor(
- element2,
- name3,
- annotation.arguments,
- );
+ constructor = _instantiateAnnotationClass(element2)
+ .lookUpConstructor(name3, _definingLibrary);
nameNode3.staticElement = constructor;
} else if (element2 == null) {
undefined = true;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 53038fc..b28a0af 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -279,7 +279,7 @@
* The elements that will be defined later in the current scope, but right
* now are not declared.
*/
- HiddenElements _hiddenElements = null;
+ HiddenElements _hiddenElements;
/**
* A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
@@ -2058,7 +2058,7 @@
*/
void _checkForAssignmentToFinal(Expression expression) {
// prepare element
- Element element = null;
+ Element element;
AstNode highlightedNode = expression;
if (expression is Identifier) {
element = expression.staticElement;
@@ -3650,7 +3650,7 @@
ExecutableElement accessorElement =
accessorDeclaration.declaredElement as ExecutableElement;
if (accessorElement is PropertyAccessorElement) {
- PropertyAccessorElement counterpartAccessor = null;
+ PropertyAccessorElement counterpartAccessor;
if (accessorElement.isGetter) {
counterpartAccessor = accessorElement.correspondingSetter;
} else {
@@ -3667,8 +3667,8 @@
return;
}
// Default of null == no accessor or no type (dynamic)
- DartType getterType = null;
- DartType setterType = null;
+ DartType getterType;
+ DartType setterType;
// Get an existing counterpart accessor if any.
if (accessorElement.isGetter) {
getterType = _getGetterType(accessorElement);
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8e6d623..58b6393 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -560,13 +560,13 @@
Annotation parseAnnotation() {
Token atSign = getAndAdvance();
Identifier name = parsePrefixedIdentifier();
- Token period = null;
- SimpleIdentifier constructorName = null;
+ Token period;
+ SimpleIdentifier constructorName;
if (_matches(TokenType.PERIOD)) {
period = getAndAdvance();
constructorName = parseSimpleIdentifier();
}
- ArgumentList arguments = null;
+ ArgumentList arguments;
if (_matches(TokenType.OPEN_PAREN)) {
arguments = parseArgumentList();
}
@@ -690,7 +690,7 @@
if (_matches(TokenType.COMMA)) {
comma = getAndAdvance();
if (_matches(TokenType.CLOSE_PAREN)) {
- comma = null;
+ comma;
} else {
message = parseExpression2();
if (_matches(TokenType.COMMA)) {
@@ -939,7 +939,7 @@
/// 'break' identifier? ';'
Statement parseBreakStatement() {
Token breakKeyword = getAndAdvance();
- SimpleIdentifier label = null;
+ SimpleIdentifier label;
if (_matchesIdentifier()) {
label = _parseSimpleIdentifierUnchecked();
}
@@ -968,8 +968,8 @@
/// assignmentOperator expressionWithoutCascade
Expression parseCascadeSection() {
Token period = getAndAdvance();
- Expression expression = null;
- SimpleIdentifier functionName = null;
+ Expression expression;
+ SimpleIdentifier functionName;
if (_matchesIdentifier()) {
functionName = _parseSimpleIdentifierUnchecked();
} else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) {
@@ -981,7 +981,7 @@
Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET);
expression = astFactory.indexExpressionForCascade(
period, leftBracket, index, rightBracket);
- period = null;
+ period;
} finally {
_inInitializer = wasInInitializer;
}
@@ -998,8 +998,8 @@
if (functionName != null) {
expression = astFactory.methodInvocation(expression, period,
functionName, typeArguments, parseArgumentList());
- period = null;
- functionName = null;
+ period;
+ functionName;
} else if (expression == null) {
// It should not be possible to get here.
expression = astFactory.methodInvocation(expression, period,
@@ -1011,7 +1011,7 @@
} while (_isLikelyArgumentList());
} else if (functionName != null) {
expression = astFactory.propertyAccess(expression, period, functionName);
- period = null;
+ period;
}
assert(expression != null);
bool progress = true;
@@ -1065,7 +1065,7 @@
Token keyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
String className = name.name;
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
TokenType type = _currentToken.type;
if (type == TokenType.LT) {
typeParameters = parseTypeParameterList();
@@ -1084,9 +1084,9 @@
// generate errors if they are not in the order required by the
// specification.
//
- ExtendsClause extendsClause = null;
- WithClause withClause = null;
- ImplementsClause implementsClause = null;
+ ExtendsClause extendsClause;
+ WithClause withClause;
+ ImplementsClause implementsClause;
bool foundClause = true;
while (foundClause) {
Keyword keyword = _currentToken.keyword;
@@ -1136,7 +1136,7 @@
//
// Look for and skip over the extra-lingual 'native' specification.
//
- NativeClause nativeClause = null;
+ NativeClause nativeClause;
if (_matchesKeyword(Keyword.NATIVE) &&
_tokenMatches(_peek(), TokenType.STRING)) {
nativeClause = _parseNativeClause();
@@ -1144,9 +1144,9 @@
//
// Parse the body of the class.
//
- Token leftBracket = null;
- List<ClassMember> members = null;
- Token rightBracket = null;
+ Token leftBracket;
+ List<ClassMember> members;
+ Token rightBracket;
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
leftBracket = getAndAdvance();
members = _parseClassMembers(className, _getEndToken(leftBracket));
@@ -1367,9 +1367,9 @@
parseSimpleIdentifier(allowKeyword: true, isDeclaration: true),
parseFormalParameterList());
} else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
- TypeName returnType = null;
+ TypeName returnType;
SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
FormalParameterList parameters = parseFormalParameterList();
if (_matches(TokenType.COLON) ||
modifiers.factoryKeyword != null ||
@@ -1484,7 +1484,7 @@
} else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
SimpleIdentifier methodName =
_parseSimpleIdentifierUnchecked(isDeclaration: true);
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
FormalParameterList parameters = parseFormalParameterList();
if (methodName.name == className) {
_reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type);
@@ -1551,7 +1551,7 @@
/// 'show' identifier (',' identifier)*
/// | 'hide' identifier (',' identifier)*
List<Combinator> parseCombinators() {
- List<Combinator> combinators = null;
+ List<Combinator> combinators;
while (true) {
Combinator combinator = parseCombinator();
if (combinator == null) {
@@ -1575,7 +1575,7 @@
// TODO(brianwilkerson) Consider making the creation of documentation
// comments be lazy.
List<DocumentationCommentToken> tokens = parseDocumentationCommentTokens();
- List<Annotation> metadata = null;
+ List<Annotation> metadata;
while (_matches(TokenType.AT)) {
metadata ??= <Annotation>[];
metadata.add(parseAnnotation());
@@ -1617,7 +1617,7 @@
return astFactory.commentReference(
null, astFactory.simpleIdentifier(syntheticToken));
}
- Token newKeyword = null;
+ Token newKeyword;
if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) {
newKeyword = firstToken;
firstToken = firstToken.next;
@@ -1715,7 +1715,7 @@
// Skip GitHub code blocks.
// https://help.github.com/articles/creating-and-highlighting-code-blocks/
if (tokens.length != 1) {
- if (comment.indexOf('```') != -1) {
+ if (comment.contains('```')) {
isInGitHubCodeBlock = !isInGitHubCodeBlock;
}
if (isInGitHubCodeBlock) {
@@ -1800,7 +1800,7 @@
/// | topLevelDeclaration
CompilationUnit parseCompilationUnit2() {
Token firstToken = _currentToken;
- ScriptTag scriptTag = null;
+ ScriptTag scriptTag;
if (_matches(TokenType.SCRIPT_TAG)) {
scriptTag = astFactory.scriptTag(getAndAdvance());
}
@@ -2081,7 +2081,7 @@
return parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, null);
} else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
- TypeName returnType = null;
+ TypeName returnType;
_validateModifiersForTopLevelFunction(modifiers);
return parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, returnType);
@@ -2196,8 +2196,8 @@
Token ifKeyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
DottedName name = parseDottedName();
- Token equalToken = null;
- StringLiteral value = null;
+ Token equalToken;
+ StringLiteral value;
if (_matches(TokenType.EQ_EQ)) {
equalToken = getAndAdvance();
value = parseStringLiteral();
@@ -2241,14 +2241,14 @@
/// fieldInitializer:
/// ('this' '.')? identifier '=' conditionalExpression cascadeSection*
ConstructorFieldInitializer parseConstructorFieldInitializer(bool hasThis) {
- Token keywordToken = null;
- Token period = null;
+ Token keywordToken;
+ Token period;
if (hasThis) {
keywordToken = getAndAdvance();
period = _expect(TokenType.PERIOD);
}
SimpleIdentifier fieldName = parseSimpleIdentifier();
- Token equals = null;
+ Token equals;
TokenType type = _currentToken.type;
if (type == TokenType.EQ) {
equals = getAndAdvance();
@@ -2298,8 +2298,8 @@
/// type ('.' identifier)?
ConstructorName parseConstructorName() {
TypeName type = parseTypeName(false);
- Token period = null;
- SimpleIdentifier name = null;
+ Token period;
+ SimpleIdentifier name;
if (_matches(TokenType.PERIOD)) {
period = getAndAdvance();
name = parseSimpleIdentifier();
@@ -2319,7 +2319,7 @@
_reportErrorForToken(
ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword);
}
- SimpleIdentifier label = null;
+ SimpleIdentifier label;
if (_matchesIdentifier()) {
label = _parseSimpleIdentifierUnchecked();
}
@@ -2373,7 +2373,7 @@
/// scriptTag? directive*
CompilationUnit parseDirectives2() {
Token firstToken = _currentToken;
- ScriptTag scriptTag = null;
+ ScriptTag scriptTag;
if (_matches(TokenType.SCRIPT_TAG)) {
scriptTag = astFactory.scriptTag(getAndAdvance());
}
@@ -2510,9 +2510,9 @@
EnumDeclaration parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
Token keyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
- Token leftBracket = null;
+ Token leftBracket;
List<EnumConstantDeclaration> constants = <EnumConstantDeclaration>[];
- Token rightBracket = null;
+ Token rightBracket;
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
leftBracket = getAndAdvance();
if (_matchesIdentifier() || _matches(TokenType.AT)) {
@@ -2720,8 +2720,8 @@
/// | type
FinalConstVarOrType parseFinalConstVarOrType(bool optional,
{bool inFunctionType: false}) {
- Token keywordToken = null;
- TypeAnnotation type = null;
+ Token keywordToken;
+ TypeAnnotation type;
Keyword keyword = _currentToken.keyword;
if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
keywordToken = getAndAdvance();
@@ -2755,7 +2755,7 @@
} else {
// Support parameters such as `(/*=K*/ key, /*=V*/ value)`
// This is not supported if the type is required.
- type = null;
+ type;
}
return new FinalConstVarOrType(keywordToken, type);
}
@@ -2883,14 +2883,14 @@
bool wasInLoop = _inLoop;
_inLoop = true;
try {
- Token awaitKeyword = null;
+ Token awaitKeyword;
if (_matchesKeyword(Keyword.AWAIT)) {
awaitKeyword = getAndAdvance();
}
Token forKeyword = _expectKeyword(Keyword.FOR);
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
- VariableDeclarationList variableList = null;
- Expression initialization = null;
+ VariableDeclarationList variableList;
+ Expression initialization;
if (!_matches(TokenType.SEMICOLON)) {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
if (_matchesIdentifier() &&
@@ -2915,8 +2915,8 @@
if (type == TokenType.COLON) {
_reportErrorForCurrentToken(ParserErrorCode.COLON_IN_PLACE_OF_IN);
}
- DeclaredIdentifier loopVariable = null;
- SimpleIdentifier identifier = null;
+ DeclaredIdentifier loopVariable;
+ SimpleIdentifier identifier;
if (variableList == null) {
// We found: <expression> 'in'
_reportErrorForCurrentToken(
@@ -2981,12 +2981,12 @@
ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword);
}
Token leftSeparator = _expect(TokenType.SEMICOLON);
- Expression condition = null;
+ Expression condition;
if (!_matches(TokenType.SEMICOLON)) {
condition = parseExpression2();
}
Token rightSeparator = _expect(TokenType.SEMICOLON);
- List<Expression> updaters = null;
+ List<Expression> updaters;
if (!_matches(TokenType.CLOSE_PAREN)) {
updaters = parseExpressionList();
}
@@ -3051,8 +3051,8 @@
}
return astFactory.emptyFunctionBody(getAndAdvance());
}
- Token keyword = null;
- Token star = null;
+ Token keyword;
+ Token star;
bool foundAsync = false;
bool foundSync = false;
if (type.isKeyword) {
@@ -3080,7 +3080,7 @@
if (keyword != null) {
if (!foundAsync) {
_reportErrorForToken(ParserErrorCode.INVALID_SYNC, keyword);
- keyword = null;
+ keyword;
} else if (star != null) {
_reportErrorForToken(
ParserErrorCode.INVALID_STAR_AFTER_ASYNC, star);
@@ -3093,7 +3093,7 @@
_advance();
}
Expression expression = parseExpression2();
- Token semicolon = null;
+ Token semicolon;
if (!inExpression) {
semicolon = _expect(TokenType.SEMICOLON);
}
@@ -3118,7 +3118,7 @@
return astFactory.blockFunctionBody(keyword, star, parseBlock());
} else if (_matchesKeyword(Keyword.NATIVE)) {
Token nativeToken = getAndAdvance();
- StringLiteral stringLiteral = null;
+ StringLiteral stringLiteral;
if (_matches(TokenType.STRING)) {
stringLiteral = _parseStringLiteralUnchecked();
}
@@ -3153,10 +3153,10 @@
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
TypeAnnotation returnType) {
- Token keywordToken = null;
+ Token keywordToken;
bool isGetter = false;
Keyword keyword = _currentToken.keyword;
- SimpleIdentifier name = null;
+ SimpleIdentifier name;
if (keyword == Keyword.GET) {
keywordToken = getAndAdvance();
isGetter = true;
@@ -3165,13 +3165,13 @@
}
if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) {
name = astFactory.simpleIdentifier(keywordToken, isDeclaration: true);
- keywordToken = null;
+ keywordToken;
isGetter = false;
} else {
name = parseSimpleIdentifier(isDeclaration: true);
}
TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
- FormalParameterList parameters = null;
+ FormalParameterList parameters;
if (!isGetter) {
if (_matches(TokenType.OPEN_PAREN)) {
parameters = _parseFormalParameterListUnchecked();
@@ -3261,7 +3261,7 @@
/// type identifier
GenericFunctionType parseGenericFunctionTypeAfterReturnType(
TypeAnnotation returnType) {
- Token functionKeyword = null;
+ Token functionKeyword;
if (_matchesKeyword(Keyword.FUNCTION)) {
functionKeyword = getAndAdvance();
} else if (_matchesIdentifier()) {
@@ -3269,7 +3269,7 @@
} else {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_FUNCTION_KEYWORD);
}
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
if (_matches(TokenType.LT)) {
typeParameters = parseTypeParameterList();
}
@@ -3288,7 +3288,7 @@
GenericTypeAlias parseGenericTypeAlias(
CommentAndMetadata commentAndMetadata, Token keyword) {
Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true);
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
if (_matches(TokenType.LT)) {
typeParameters = parseTypeParameterList();
}
@@ -3406,8 +3406,8 @@
Expression condition = parseExpression2();
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
Statement thenStatement = parseStatement2();
- Token elseKeyword = null;
- Statement elseStatement = null;
+ Token elseKeyword;
+ Statement elseStatement;
if (_matchesKeyword(Keyword.ELSE)) {
elseKeyword = getAndAdvance();
elseStatement = parseStatement2();
@@ -3444,9 +3444,9 @@
Token importKeyword = getAndAdvance();
StringLiteral libraryUri = _parseUri();
List<Configuration> configurations = _parseConfigurations();
- Token deferredToken = null;
- Token asToken = null;
- SimpleIdentifier prefix = null;
+ Token deferredToken;
+ Token asToken;
+ SimpleIdentifier prefix;
if (_matchesKeyword(Keyword.DEFERRED)) {
deferredToken = getAndAdvance();
}
@@ -4102,8 +4102,8 @@
}
FinalConstVarOrType holder = parseFinalConstVarOrType(!inFunctionType,
inFunctionType: inFunctionType);
- Token thisKeyword = null;
- Token period = null;
+ Token thisKeyword;
+ Token period;
if (_matchesKeyword(Keyword.THIS)) {
thisKeyword = getAndAdvance();
period = _expect(TokenType.PERIOD);
@@ -4339,7 +4339,7 @@
return parseStringLiteral();
} else if (type == TokenType.INT) {
Token token = getAndAdvance();
- int value = null;
+ int value;
try {
value = int.parse(token.lexeme);
} on FormatException {
@@ -4374,7 +4374,7 @@
return astFactory.doubleLiteral(token, value);
} else if (type == TokenType.HEXADECIMAL) {
Token token = getAndAdvance();
- int value = null;
+ int value;
try {
value = int.parse(token.lexeme);
} on FormatException {
@@ -4443,8 +4443,8 @@
RedirectingConstructorInvocation parseRedirectingConstructorInvocation(
bool hasPeriod) {
Token keyword = getAndAdvance();
- Token period = null;
- SimpleIdentifier constructorName = null;
+ Token period;
+ SimpleIdentifier constructorName;
if (hasPeriod) {
period = getAndAdvance();
if (_matchesIdentifier()) {
@@ -4482,7 +4482,7 @@
expression, asOperator, parseTypeNotVoid(true));
} else if (keyword == Keyword.IS) {
Token isOperator = getAndAdvance();
- Token notOperator = null;
+ Token notOperator;
if (_matches(TokenType.BANG)) {
notOperator = getAndAdvance();
}
@@ -4614,7 +4614,7 @@
}
_treeDepth++;
try {
- List<Label> labels = null;
+ List<Label> labels;
while (
_matchesIdentifier() && _currentToken.next.type == TokenType.COLON) {
Label label = parseLabel(isDeclaration: true);
@@ -4664,8 +4664,8 @@
/// 'super' ('.' identifier)? arguments
SuperConstructorInvocation parseSuperConstructorInvocation() {
Token keyword = getAndAdvance();
- Token period = null;
- SimpleIdentifier constructorName = null;
+ Token period;
+ SimpleIdentifier constructorName;
if (_matches(TokenType.PERIOD)) {
period = getAndAdvance();
constructorName = parseSimpleIdentifier();
@@ -4695,7 +4695,7 @@
Expression expression = parseExpression2();
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
- Token defaultKeyword = null;
+ Token defaultKeyword;
List<SwitchMember> members = <SwitchMember>[];
TokenType type = _currentToken.type;
while (type != TokenType.EOF && type != TokenType.CLOSE_CURLY_BRACKET) {
@@ -4852,20 +4852,20 @@
Token tryKeyword = getAndAdvance();
Block body = _parseBlockChecked();
List<CatchClause> catchClauses = <CatchClause>[];
- Block finallyClause = null;
+ Block finallyClause;
while (_matchesKeyword(Keyword.ON) || _matchesKeyword(Keyword.CATCH)) {
- Token onKeyword = null;
- TypeName exceptionType = null;
+ Token onKeyword;
+ TypeName exceptionType;
if (_matchesKeyword(Keyword.ON)) {
onKeyword = getAndAdvance();
exceptionType = parseTypeNotVoid(false);
}
- Token catchKeyword = null;
- Token leftParenthesis = null;
- SimpleIdentifier exceptionParameter = null;
- Token comma = null;
- SimpleIdentifier stackTraceParameter = null;
- Token rightParenthesis = null;
+ Token catchKeyword;
+ Token leftParenthesis;
+ SimpleIdentifier exceptionParameter;
+ Token comma;
+ SimpleIdentifier stackTraceParameter;
+ Token rightParenthesis;
if (_matchesKeyword(Keyword.CATCH)) {
catchKeyword = getAndAdvance();
leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -4888,7 +4888,7 @@
rightParenthesis,
catchBody));
}
- Token finallyKeyword = null;
+ Token finallyKeyword;
if (_matchesKeyword(Keyword.FINALLY)) {
finallyKeyword = getAndAdvance();
finallyClause = _parseBlockChecked();
@@ -4942,7 +4942,7 @@
/// typeWithoutFunction
/// | functionType
TypeAnnotation parseTypeAnnotation(bool inExpression) {
- TypeAnnotation type = null;
+ TypeAnnotation type;
if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
// Generic function type with no return type.
type = parseGenericFunctionTypeAfterReturnType(null);
@@ -4994,7 +4994,7 @@
/// functionType
/// | typeNotVoidWithoutFunction
TypeAnnotation parseTypeNotVoid(bool inExpression) {
- TypeAnnotation type = null;
+ TypeAnnotation type;
if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
// Generic function type with no return type.
type = parseGenericFunctionTypeAfterReturnType(null);
@@ -5150,8 +5150,8 @@
// user is in the middle of inserting "int bar;" prior to
// "@deprecated foo() {}").
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
- Token equals = null;
- Expression initializer = null;
+ Token equals;
+ Expression initializer;
if (_matches(TokenType.EQ)) {
equals = getAndAdvance();
initializer = parseExpression2();
@@ -5268,7 +5268,7 @@
/// 'yield' '*'? expression ';'
YieldStatement parseYieldStatement() {
Token yieldToken = getAndAdvance();
- Token star = null;
+ Token star;
if (_matches(TokenType.STAR)) {
star = getAndAdvance();
}
@@ -5390,7 +5390,7 @@
///
/// This method must be kept in sync with [parseTypeAnnotation].
Token skipTypeAnnotation(Token startToken) {
- Token next = null;
+ Token next;
if (_atGenericFunctionTypeAfterReturnType(startToken)) {
// Generic function type with no return type.
next = skipGenericFunctionTypeAfterReturnType(startToken);
@@ -6053,7 +6053,7 @@
if (_matches(TokenType.COMMA)) {
comma = getAndAdvance();
if (_matches(TokenType.CLOSE_PAREN)) {
- comma = null;
+ comma;
} else {
message = parseExpression2();
if (_matches(TokenType.COMMA)) {
@@ -6142,14 +6142,14 @@
TypeParameterList typeParameters) {
Token equals = _expect(TokenType.EQ);
TypeName superclass = parseTypeName(false);
- WithClause withClause = null;
+ WithClause withClause;
if (_matchesKeyword(Keyword.WITH)) {
withClause = parseWithClause();
} else {
_reportErrorForCurrentToken(
ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.lexeme]);
}
- ImplementsClause implementsClause = null;
+ ImplementsClause implementsClause;
if (_matchesKeyword(Keyword.IMPLEMENTS)) {
implementsClause = parseImplementsClause();
}
@@ -6186,7 +6186,7 @@
/// Parse a list of configurations. Return the configurations that were
/// parsed, or `null` if there are no configurations.
List<Configuration> _parseConfigurations() {
- List<Configuration> configurations = null;
+ List<Configuration> configurations;
while (_matchesKeyword(Keyword.IF)) {
configurations ??= <Configuration>[];
configurations.add(parseConfiguration());
@@ -6204,8 +6204,8 @@
SimpleIdentifier name,
FormalParameterList parameters) {
bool bodyAllowed = externalKeyword == null;
- Token separator = null;
- List<ConstructorInitializer> initializers = null;
+ Token separator;
+ List<ConstructorInitializer> initializers;
if (_matches(TokenType.COLON)) {
separator = getAndAdvance();
initializers = <ConstructorInitializer>[];
@@ -6239,7 +6239,7 @@
ParserErrorCode.FACTORY_WITH_INITIALIZERS, factoryKeyword);
}
}
- ConstructorName redirectedConstructor = null;
+ ConstructorName redirectedConstructor;
FunctionBody body;
if (_matches(TokenType.EQ)) {
separator = getAndAdvance();
@@ -6333,17 +6333,17 @@
// better.
//
List<FormalParameter> parameters = <FormalParameter>[];
- Token leftSquareBracket = null;
- Token rightSquareBracket = null;
- Token leftCurlyBracket = null;
- Token rightCurlyBracket = null;
+ Token leftSquareBracket;
+ Token rightSquareBracket;
+ Token leftCurlyBracket;
+ Token rightCurlyBracket;
ParameterKind kind = ParameterKind.REQUIRED;
bool firstParameter = true;
bool reportedMultiplePositionalGroups = false;
bool reportedMultipleNamedGroups = false;
bool reportedMixedGroups = false;
bool wasOptionalParameter = false;
- Token initialToken = null;
+ Token initialToken;
do {
if (firstParameter) {
firstParameter = false;
@@ -6430,7 +6430,7 @@
ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
['}', ']']);
rightCurlyBracket = rightSquareBracket;
- rightSquareBracket = null;
+ rightSquareBracket;
// Skip over synthetic closer inserted by fasta
// since we've already reported an error
if (_currentToken.type == TokenType.CLOSE_CURLY_BRACKET &&
@@ -6452,7 +6452,7 @@
ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
[']', '}']);
rightSquareBracket = rightCurlyBracket;
- rightCurlyBracket = null;
+ rightCurlyBracket;
// Skip over synthetic closer inserted by fasta
// since we've already reported an error
if (_currentToken.type == TokenType.CLOSE_SQUARE_BRACKET &&
@@ -6535,12 +6535,12 @@
/// returnType? name
FunctionTypeAlias _parseFunctionTypeAlias(
CommentAndMetadata commentAndMetadata, Token keyword) {
- TypeAnnotation returnType = null;
+ TypeAnnotation returnType;
if (hasReturnTypeInTypeAlias) {
returnType = parseTypeAnnotation(false);
}
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
- TypeParameterList typeParameters = null;
+ TypeParameterList typeParameters;
if (_matches(TokenType.LT)) {
typeParameters = parseTypeParameterList();
}
@@ -6989,7 +6989,7 @@
}
} else {
Token openToken = getAndAdvance();
- Expression expression = null;
+ Expression expression;
if (_matchesKeyword(Keyword.THIS)) {
expression = astFactory.thisExpression(getAndAdvance());
} else {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 16c150d..1a6ab3f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1864,7 +1864,7 @@
/// Return `true` if the given [expression] is resolved to a constant
/// variable.
bool _isDebugConstant(Expression expression) {
- Element element = null;
+ Element element;
if (expression is Identifier) {
element = expression.staticElement;
} else if (expression is PropertyAccess) {
@@ -3044,22 +3044,22 @@
/// The class declaration representing the class containing the current node,
/// or `null` if the current node is not contained in a class.
- ClassDeclaration _enclosingClassDeclaration = null;
+ ClassDeclaration _enclosingClassDeclaration;
/// The function type alias representing the function type containing the
/// current node, or `null` if the current node is not contained in a function
/// type alias.
- FunctionTypeAlias _enclosingFunctionTypeAlias = null;
+ FunctionTypeAlias _enclosingFunctionTypeAlias;
/// The element representing the function containing the current node, or
/// `null` if the current node is not contained in a function.
- ExecutableElement _enclosingFunction = null;
+ ExecutableElement _enclosingFunction;
/// The mixin declaration representing the class containing the current node,
/// or `null` if the current node is not contained in a mixin.
- MixinDeclaration _enclosingMixinDeclaration = null;
+ MixinDeclaration _enclosingMixinDeclaration;
- InferenceContext inferenceContext = null;
+ InferenceContext inferenceContext;
/// The object keeping track of which elements have had their types promoted.
TypePromotionManager _promoteManager;
@@ -3171,7 +3171,7 @@
}
}
- NullabilitySuffix get _noneOrStarSuffix {
+ NullabilitySuffix get noneOrStarSuffix {
return _nonNullableEnabled
? NullabilitySuffix.none
: NullabilitySuffix.star;
@@ -3189,7 +3189,7 @@
/// @param expression the expression with which the element is associated
/// @return the element associated with the given expression
VariableElement getOverridableStaticElement(Expression expression) {
- Element element = null;
+ Element element;
if (expression is SimpleIdentifier) {
element = expression.staticElement;
} else if (expression is PrefixedIdentifier) {
@@ -3241,7 +3241,7 @@
// parameter and return type are in terms of the surrounding context.
return fnType.instantiate(typeParameters.map((TypeParameter t) {
return t.declaredElement.instantiate(
- nullabilitySuffix: _noneOrStarSuffix,
+ nullabilitySuffix: noneOrStarSuffix,
);
}).toList());
}
@@ -4312,9 +4312,9 @@
// because it needs to be visited in the context of the constructor
// invocation.
//
+ node.accept(elementResolver);
InferenceContext.setType(node.argumentList, node.staticElement?.type);
node.argumentList?.accept(this);
- node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4419,9 +4419,9 @@
// because it needs to be visited in the context of the constructor
// invocation.
//
+ node.accept(elementResolver);
InferenceContext.setType(node.argumentList, node.staticElement?.type);
node.argumentList?.accept(this);
- node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -4994,7 +4994,7 @@
int requiredParameterCount = 0;
int unnamedParameterCount = 0;
List<ParameterElement> unnamedParameters = new List<ParameterElement>();
- Map<String, ParameterElement> namedParameters = null;
+ Map<String, ParameterElement> namedParameters;
int length = parameters.length;
for (int i = 0; i < length; i++) {
ParameterElement parameter = parameters[i];
@@ -5016,7 +5016,7 @@
List<ParameterElement> resolvedParameters =
new List<ParameterElement>(argumentCount);
int positionalArgumentCount = 0;
- HashSet<String> usedNames = null;
+ HashSet<String> usedNames;
bool noBlankArguments = true;
for (int i = 0; i < argumentCount; i++) {
Expression argument = arguments[i];
@@ -6124,7 +6124,7 @@
return;
}
- DartType type = null;
+ DartType type;
if (element == DynamicElementImpl.instance) {
_setElement(typeName, element);
type = DynamicTypeImpl.instance;
@@ -6548,8 +6548,8 @@
final Source source;
final AnalysisErrorListener errorListener;
- Scope libraryScope = null;
- TypeNameResolver typeNameResolver = null;
+ Scope libraryScope;
+ TypeNameResolver typeNameResolver;
TypeParameterBoundsResolver(this.typeSystem, this.library, this.source,
this.errorListener, FeatureSet featureSet)
@@ -6636,7 +6636,7 @@
void _resolveTypeParameters(
TypeParameterList typeParameters, Scope createTypeParametersScope()) {
if (typeParameters != null) {
- Scope typeParametersScope = null;
+ Scope typeParametersScope;
for (TypeParameter typeParameter in typeParameters.typeParameters) {
TypeAnnotation bound = typeParameter.bound;
if (bound != null) {
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 67dfd49..f981dcf 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -367,7 +367,7 @@
@override
void visitMapLiteralEntry(MapLiteralEntry node) {
- String libraryName = null;
+ String libraryName;
Expression key = node.key;
if (key is SimpleStringLiteral) {
libraryName = "$_LIBRARY_PREFIX${key.value}";
@@ -486,7 +486,7 @@
* 'lib' directory within the SDK.
*/
@override
- String path = null;
+ String path;
/**
* The name of the category containing the library. Unless otherwise specified
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index e8108bb..5d44d4b 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -107,9 +107,21 @@
* inferred type parameters found by the resolver.
*/
void inferConstructorName(ConstructorName node, InterfaceType type) {
+ // TODO(scheglov) Inline.
node.type.type = type;
- if (type != _typeSystem.instantiateToBounds(type.element.type)) {
- _resolver.inferenceContext.recordInference(node.parent, type);
+ // TODO(scheglov) Remove when DDC stops using analyzer.
+ var element = type.element;
+ if (element.typeParameters.isNotEmpty) {
+ var typeParameterBounds = _typeSystem.instantiateTypeFormalsToBounds(
+ element.typeParameters,
+ );
+ var instantiatedToBounds = element.instantiate(
+ typeArguments: typeParameterBounds,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
+ if (type != instantiatedToBounds) {
+ _resolver.inferenceContext.recordInference(node.parent, type);
+ }
}
}
@@ -1389,13 +1401,13 @@
}
ClassElement returnType = library.getType(elementName);
if (returnType != null) {
- if (returnType.typeParameters.isNotEmpty) {
- // Caller can't deal with unbound type parameters, so substitute
- // `dynamic`.
- return returnType.type.instantiate(
- returnType.typeParameters.map((_) => _dynamicType).toList());
- }
- return returnType.type;
+ return returnType.instantiate(
+ typeArguments: List.filled(
+ returnType.typeParameters.length,
+ _dynamicType,
+ ),
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
}
return null;
@@ -1802,7 +1814,7 @@
e.library.source.uri.toString() == 'dart:_foreign_helper' &&
e.name == 'JS') {
String typeStr = _getFirstArgumentAsString(node.argumentList);
- DartType returnType = null;
+ DartType returnType;
if (typeStr == '-dynamic') {
returnType = _typeProvider.bottomType;
} else {
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index f6687b4..810d916 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -1345,7 +1345,7 @@
TokenFactory.tokenFromKeyword(Keyword.EXTENDS), bound);
static TypeParameterList typeParameterList([List<String> typeNames]) {
- List<TypeParameter> typeParameters = null;
+ List<TypeParameter> typeParameters;
if (typeNames != null && typeNames.isNotEmpty) {
typeParameters = new List<TypeParameter>();
for (String typeName in typeNames) {
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 7a84adf..d64f2d5 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -361,7 +361,7 @@
}
List<TypeParameterElement> getFreeParameters(DartType rootType) {
- List<TypeParameterElement> parameters = null;
+ List<TypeParameterElement> parameters;
Set<DartType> visitedTypes = new HashSet<DartType>();
void appendParameters(DartType type) {
@@ -1174,7 +1174,7 @@
}
static List<T> _transformList<T>(List<T> list, T f(T t)) {
- List<T> newList = null;
+ List<T> newList;
for (var i = 0; i < list.length; i++) {
var item = list[i];
var newItem = f(item);
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 52439ce..8217608 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1266,8 +1266,8 @@
}
}
- String docComplete = null;
- String docSummary = null;
+ String docComplete;
+ String docSummary;
void setDartDoc(AnnotatedNode node) {
if (node.documentationComment != null) {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index bb96dd0..ff48204 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -381,8 +381,14 @@
_indexUnitDeclarations(unitContext, unitRef, unitNode);
}
- MethodElementImpl _method(ClassElementImpl enclosing, Reference reference) {
- enclosing.methods;
+ MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
+ if (enclosing is ClassElementImpl) {
+ enclosing.methods;
+ } else if (enclosing is ExtensionElementImpl) {
+ enclosing.methods;
+ } else {
+ throw StateError('${enclosing.runtimeType}');
+ }
// Requesting methods sets elements for all of them.
assert(reference.element != null);
return reference.element;
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index ac7435a..5d77644 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -10,15 +10,18 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/summary2/ast_resolver.dart';
import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
class MetadataResolver extends ThrowingAstVisitor<void> {
final Linker _linker;
final LibraryElement _libraryElement;
final Scope _libraryScope;
final CompilationUnitElement _unitElement;
+ Scope _scope;
- MetadataResolver(this._linker, this._libraryElement, this._libraryScope,
- this._unitElement);
+ MetadataResolver(
+ this._linker, this._libraryElement, this._libraryScope, this._unitElement)
+ : _scope = _libraryScope;
@override
void visitAnnotation(Annotation node) {
@@ -27,7 +30,7 @@
var holder = ElementHolder();
node.accept(LocalElementBuilder(holder, null));
- var astResolver = AstResolver(_linker, _libraryElement, _libraryScope);
+ var astResolver = AstResolver(_linker, _libraryElement, _scope);
astResolver.rewriteAst(node);
astResolver.resolve(node);
}
@@ -36,7 +39,13 @@
void visitClassDeclaration(ClassDeclaration node) {
node.metadata.accept(this);
node.typeParameters?.accept(this);
- node.members.accept(this);
+
+ _scope = LinkingNodeContext.get(node).scope;
+ try {
+ node.members.accept(this);
+ } finally {
+ _scope = _libraryScope;
+ }
}
@override
@@ -82,7 +91,13 @@
void visitExtensionDeclaration(ExtensionDeclaration node) {
node.metadata.accept(this);
node.typeParameters?.accept(this);
- node.members.accept(this);
+
+ _scope = LinkingNodeContext.get(node).scope;
+ try {
+ node.members.accept(this);
+ } finally {
+ _scope = _libraryScope;
+ }
}
@override
@@ -161,7 +176,13 @@
void visitMixinDeclaration(MixinDeclaration node) {
node.metadata.accept(this);
node.typeParameters?.accept(this);
- node.members.accept(this);
+
+ _scope = LinkingNodeContext.get(node).scope;
+ try {
+ node.members.accept(this);
+ } finally {
+ _scope = _libraryScope;
+ }
}
@override
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 2cef609..76b23f9 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -94,9 +94,9 @@
variable.initializer.accept(LocalElementBuilder(holder, null));
(element as VariableElementImpl).encloseElements(holder.functions);
- InferenceContext.setType(variable.initializer, typeNode.type);
var astResolver = AstResolver(linker, _library, _scope);
astResolver.rewriteAst(variable.initializer);
+ InferenceContext.setType(variable.initializer, typeNode.type);
astResolver.resolve(variable.initializer);
}
}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3a196922..0c0a8e6 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1012,7 +1012,7 @@
var type = functionType.returnType;
- ClassElement expectedElement = null;
+ ClassElement expectedElement;
if (body.isAsynchronous) {
if (body.isGenerator) {
// Stream<T> -> T
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index d0e19d8..a4707b5 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -147,7 +147,7 @@
*/
DartType _computeParameterType(ParameterElement parameter, int index,
List<FunctionType> overriddenTypes) {
- DartType parameterType = null;
+ DartType parameterType;
int length = overriddenTypes.length;
for (int i = 0; i < length; i++) {
ParameterElement matchingParameter = _getCorrespondingParameter(
@@ -191,7 +191,7 @@
* want to be smarter about it.
*/
DartType _computeReturnType(Iterable<DartType> overriddenReturnTypes) {
- DartType returnType = null;
+ DartType returnType;
for (DartType type in overriddenReturnTypes) {
if (type == null) {
type = typeProvider.dynamicType;
@@ -567,7 +567,7 @@
* Initialize a newly created gatherer to gather all of the variables that
* pass the given [filter] (or all variables if no filter is provided).
*/
- VariableGatherer([this.filter = null]);
+ VariableGatherer([this.filter]);
@override
void visitSimpleIdentifier(SimpleIdentifier node) {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 7e9a9ed..87a5af6 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -35,6 +35,10 @@
return _node(search, (n) => n is Block);
}
+ BooleanLiteral booleanLiteral(String search) {
+ return _node(search, (n) => n is BooleanLiteral);
+ }
+
BreakStatement breakStatement(String search) {
return _node(search, (n) => n is BreakStatement);
}
@@ -75,6 +79,10 @@
return _node(search, (n) => n is DoStatement);
}
+ DoubleLiteral doubleLiteral(String search) {
+ return _node(search, (n) => n is DoubleLiteral);
+ }
+
ExportDirective export(String search) {
return _node(search, (n) => n is ExportDirective);
}
@@ -179,6 +187,10 @@
return _node(search, (n) => n is NamedExpression);
}
+ NullLiteral nullLiteral(String search) {
+ return _node(search, (n) => n is NullLiteral);
+ }
+
ParenthesizedExpression parenthesized(String search) {
return _node(search, (n) => n is ParenthesizedExpression);
}
@@ -239,6 +251,10 @@
return _node(search, (n) => n is SwitchStatement);
}
+ SymbolLiteral symbolLiteral(String search) {
+ return _node(search, (n) => n is SymbolLiteral);
+ }
+
ThisExpression this_(String search) {
return _node(search, (n) => n is ThisExpression);
}
@@ -290,7 +306,7 @@
AstNode _node(String search, bool Function(AstNode) predicate) {
var index = content.indexOf(search);
- if (content.indexOf(search, index + 1) != -1) {
+ if (content.contains(search, index + 1)) {
throw new StateError('The pattern |$search| is not unique in:\n$content');
}
if (index < 0) {
diff --git a/pkg/analyzer/lib/src/util/glob.dart b/pkg/analyzer/lib/src/util/glob.dart
index 97c122f..0283753 100644
--- a/pkg/analyzer/lib/src/util/glob.dart
+++ b/pkg/analyzer/lib/src/util/glob.dart
@@ -81,8 +81,8 @@
static bool _hasJustPrefix(String pattern, String prefix) {
if (pattern.startsWith(prefix)) {
int prefixLength = prefix.length;
- return pattern.indexOf('*', prefixLength) == -1 &&
- pattern.indexOf('?', prefixLength) == -1;
+ return !pattern.contains('*', prefixLength) &&
+ !pattern.contains('?', prefixLength);
}
return false;
}
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index d66c851..5fcbbaf 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -80,7 +80,7 @@
String fileUriPart = uriPath.substring(slash + 1);
String filePath = fileUriPart.replaceAll('/', _context.separator);
- if (packageName.indexOf('.') == -1) {
+ if (!packageName.contains('.')) {
String fullFilePath = _context.join(_workspace.root, 'third_party',
'dart', packageName, 'lib', filePath);
File file = _workspace.findFile(fullFilePath);
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 4a90853..db57bbb 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -165,6 +165,10 @@
var v = const A(foo);
''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 116, 3),
+ error(
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ 116,
+ 3),
]);
}
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 6a4c187..8f4902a7 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -588,7 +588,7 @@
test_visitConstructorName_unnamed() async {
ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
+ String constructorName;
ConstructorElement constructor =
ElementFactory.constructorElement2(classA, constructorName);
classA.constructors = <ConstructorElement>[constructor];
@@ -738,7 +738,7 @@
test_visitInstanceCreationExpression_unnamed() async {
ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
+ String constructorName;
ConstructorElement constructor =
ElementFactory.constructorElement2(classA, constructorName);
classA.constructors = <ConstructorElement>[constructor];
@@ -754,7 +754,7 @@
test_visitInstanceCreationExpression_unnamed_namedParameter() async {
ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
+ String constructorName;
ConstructorElementImpl constructor =
ElementFactory.constructorElement2(classA, constructorName);
String parameterName = "a";
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index fc6c5d50c..d3e8852 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -2,13 +2,10 @@
// 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/error/error.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'resolver_test_case.dart';
+import '../src/dart/resolution/driver_resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -17,221 +14,203 @@
}
@reflectiveTest
-class ErrorSuppressionTest extends ResolverTestCase {
+class ErrorSuppressionTest extends DriverResolutionTest {
String get ignoredCode => 'const_initialized_with_non_constant_value';
- List<ErrorCode> get reportedCodes => [
- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
- ];
-
- List<ErrorCode> get reportedCodesWithAssignment => [
- StaticTypeWarningCode.INVALID_ASSIGNMENT,
- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
- ];
-
test_error_code_mismatch() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
// ignore: $ignoredCode
int x = '';
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodesWithAssignment);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 61, 2),
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 75,
+ 1),
+ ]);
}
test_ignore_first() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
// ignore: invalid_assignment
int x = '';
// ... but no ignore here ...
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodes);
+''', [
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+ 1),
+ ]);
}
test_ignore_first_trailing() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = ''; // ignore: invalid_assignment
// ... but no ignore here ...
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodes);
+''', [
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+ 1),
+ ]);
}
test_ignore_for_file() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = ''; //INVALID_ASSIGNMENT
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// ignore_for_file: invalid_assignment
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodes);
+''', [
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+ 1),
+ ]);
}
test_ignore_for_file_whitespace_variant() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
//ignore_for_file: $ignoredCode , invalid_assignment
int x = ''; //INVALID_ASSIGNMENT
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_ignore_only_trailing() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = ''; // ignore: invalid_assignment
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_ignore_second() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
//INVALID_ASSIGNMENT
int x = '';
// ignore: $ignoredCode
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+ ]);
}
test_ignore_second_trailing() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
//INVALID_ASSIGNMENT
int x = '';
const y = x; // ignore: $ignoredCode
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+ ]);
}
test_ignore_upper_case() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = ''; // ignore: INVALID_ASSIGNMENT
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_invalid_error_code() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
// ignore: right_format_wrong_code
int x = '';
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodesWithAssignment);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 2),
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 57,
+ 1),
+ ]);
}
test_missing_error_codes() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = 3;
// ignore:
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodesWithAssignment);
+''', [
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 43,
+ 1),
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 1),
+ ]);
}
test_missing_metadata_suffix() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
// ignore invalid_assignment
String y = 3; //INVALID_ASSIGNMENT
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 40, 1),
+ ]);
}
test_multiple_comments() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = ''; //This is the first comment...
// ignore: $ignoredCode
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+ ]);
}
test_multiple_ignore_for_files() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = ''; //INVALID_ASSIGNMENT
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// ignore_for_file: invalid_assignment,$ignoredCode
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_multiple_ignores() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = 3;
// ignore: invalid_assignment, $ignoredCode
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_multiple_ignores_trailing() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = 3;
const String y = x; // ignore: invalid_assignment, $ignoredCode
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_multiple_ignores_whitespace_variant_1() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = 3;
//ignore:invalid_assignment,$ignoredCode
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_multiple_ignores_whitespace_variant_2() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = 3;
//ignore: invalid_assignment,$ignoredCode
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_multiple_ignores_whitespace_variant_3() async {
- Source source = addSource('''
+ await assertNoErrorsInCode('''
int x = 3;
// ignore: invalid_assignment,$ignoredCode
const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
''');
- await computeAnalysisResult(source);
- assertErrors(source, []);
}
test_no_ignores() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = ''; //INVALID_ASSIGNMENT
const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
- await computeAnalysisResult(source);
- assertErrors(source, reportedCodesWithAssignment);
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+ error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+ 1),
+ ]);
}
test_trailing_not_above() async {
- Source source = addSource('''
+ await assertErrorsInCode('''
int x = ''; // ignore: invalid_assignment
int y = '';
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticTypeWarningCode.INVALID_ASSIGNMENT,
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 50, 2),
]);
}
}
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index e97dbde..f5d274f 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -166,6 +166,29 @@
''');
}
+ test_fuzz_15() async {
+ // `@A` is not a valid annotation, it is missing arguments.
+ // There was a bug that we did not check for arguments being missing.
+ await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A
+class B {}
+''');
+ }
+
+ test_fuzz_16() async {
+ // The default constructor of `A` does not have formal parameters.
+ // But we give it arguments.
+ // There was a bug that we did not check for this mismatch.
+ await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A(0)
+class B {}
+''');
+ }
+
test_fuzz_38091() async {
// https://github.com/dart-lang/sdk/issues/38091
// this caused an infinite loop in parser recovery
diff --git a/pkg/analyzer/test/generated/issues_test.dart b/pkg/analyzer/test/generated/issues_test.dart
index 93b97b9..198943b 100644
--- a/pkg/analyzer/test/generated/issues_test.dart
+++ b/pkg/analyzer/test/generated/issues_test.dart
@@ -16,6 +16,26 @@
/// not obvious where to put the test otherwise.
@reflectiveTest
class IssuesTest extends DriverResolutionTest {
+ /// https://github.com/dart-lang/sdk/issues/38565
+ ///
+ /// The issue was that type inference for annotation instantiation
+ /// was done incorrectly, without resolving arguments to the annotation
+ /// constructor. So, we were trying to perform type inference using null
+ /// types of arguments.
+ test_issue38565() async {
+ await resolveTestCode('''
+class A<T> {
+ const A(int a);
+}
+
+class C {
+ @A(0)
+ int field;
+}
+''');
+ // Should not crash.
+ }
+
/// https://github.com/dart-lang/sdk/issues/38589
test_issue38589() async {
await resolveTestCode('''
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index b219c94..75f8910 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -3,11 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source_io.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../src/dart/resolution/driver_resolution.dart';
-import 'resolver_test_case.dart';
+import 'test_support.dart';
main() {
defineReflectiveSuite(() {
@@ -190,22 +189,24 @@
}
}
-class PubSuggestionCodeTest extends ResolverTestCase {
+class PubSuggestionCodeTest extends DriverResolutionTest {
// TODO(brianwilkerson) The tests in this class are not being run, and all but
// the first would fail. We should implement these checks and enable the
// tests.
test_import_package() async {
await assertErrorsInCode('''
import 'package:somepackage/other.dart';
-''', [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+''', [
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+ ]);
}
test_import_packageWithDotDot() async {
await assertErrorsInCode('''
import 'package:somepackage/../other.dart';
''', [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+ error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
]);
}
@@ -213,71 +214,70 @@
await assertErrorsInCode('''
import 'package:../other.dart';
''', [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+ error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
]);
}
test_import_referenceIntoLibDirectory() async {
- addNamedSource("/myproj/pubspec.yaml", "");
- addNamedSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- await computeAnalysisResult(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+ newFile("/myproj/pubspec.yaml", content: "");
+ newFile("/myproj/lib/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/web/test.dart", "import '../lib/other.dart';", [
+ error(HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, 0, 0),
+ ]);
}
test_import_referenceIntoLibDirectory_no_pubspec() async {
- addNamedSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- await computeAnalysisResult(source);
- assertNoErrors(source);
+ newFile("/myproj/lib/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/web/test.dart", "import '../lib/other.dart';", []);
}
test_import_referenceOutOfLibDirectory() async {
- addNamedSource("/myproj/pubspec.yaml", "");
- addNamedSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- await computeAnalysisResult(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+ newFile("/myproj/pubspec.yaml", content: "");
+ newFile("/myproj/web/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/lib/test.dart", "import '../web/other.dart';", [
+ error(HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, 0, 0),
+ ]);
}
test_import_referenceOutOfLibDirectory_no_pubspec() async {
- addNamedSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- await computeAnalysisResult(source);
- assertNoErrors(source);
+ newFile("/myproj/web/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/lib/test.dart", "import '../web/other.dart';", []);
}
test_import_valid_inside_lib1() async {
- addNamedSource("/myproj/pubspec.yaml", "");
- addNamedSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
- await computeAnalysisResult(source);
- assertNoErrors(source);
+ newFile("/myproj/pubspec.yaml", content: "");
+ newFile("/myproj/lib/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/lib/test.dart", "import 'other.dart';", []);
}
test_import_valid_inside_lib2() async {
- addNamedSource("/myproj/pubspec.yaml", "");
- addNamedSource("/myproj/lib/bar/other.dart", "");
- Source source = addNamedSource(
- "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
- await computeAnalysisResult(source);
- assertNoErrors(source);
+ newFile("/myproj/pubspec.yaml", content: "");
+ newFile("/myproj/lib/bar/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/lib/foo/test.dart", "import '../bar/other.dart';", []);
}
test_import_valid_outside_lib() async {
- addNamedSource("/myproj/pubspec.yaml", "");
- addNamedSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
- await computeAnalysisResult(source);
- assertNoErrors(source);
+ newFile("/myproj/pubspec.yaml", content: "");
+ newFile("/myproj/web/other.dart", content: "");
+ await _assertErrorsInCodeInFile(
+ "/myproj/lib2/test.dart", "import '../web/other.dart';", []);
+ }
+
+ Future<void> _assertErrorsInCodeInFile(
+ String path, String content, List<ExpectedError> expectedErrors) async {
+ path = convertPath(path);
+ newFile(path, content: content);
+ result = await resolveFile(path);
+
+ var errorListener = new GatheringErrorListener();
+ errorListener.addAll(result.errors);
+ errorListener.assertErrors(expectedErrors);
}
}
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index c92e79d..11a75d9 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1681,6 +1681,34 @@
expect(extension.members, hasLength(0));
}
+ void test_constructor_named() {
+ var unit = parseCompilationUnit('''
+extension E on C {
+ E.named();
+}
+class C {}
+''', errors: [
+ expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+ ]);
+ expect(unit.declarations, hasLength(2));
+ var extension = unit.declarations[0] as ExtensionDeclaration;
+ expect(extension.members, hasLength(0));
+ }
+
+ void test_constructor_unnamed() {
+ var unit = parseCompilationUnit('''
+extension E on C {
+ E();
+}
+class C {}
+''', errors: [
+ expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+ ]);
+ expect(unit.declarations, hasLength(2));
+ var extension = unit.declarations[0] as ExtensionDeclaration;
+ expect(extension.members, hasLength(0));
+ }
+
void test_missing_on() {
var unit = parseCompilationUnit('extension E', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
@@ -1802,133 +1830,6 @@
}
}
-@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.
@@ -2959,6 +2860,21 @@
parseCompilationUnit('f() { var x = g!.x + 7; }');
}
+ void test_nullCheckBeforeIndex() {
+ // https://github.com/dart-lang/sdk/issues/37708
+ var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
+ var funct = unit.declarations[0] as FunctionDeclaration;
+ var body = funct.functionExpression.body as BlockFunctionBody;
+ var statement = body.block.statements[0] as ExpressionStatement;
+ var expression = statement.expression as IndexExpression;
+ expect(expression.index.toSource(), 'arg');
+ var propertyAccess = expression.target as PropertyAccess;
+ expect(propertyAccess.propertyName.toSource(), 'baz');
+ var target = propertyAccess.target as PostfixExpression;
+ expect(target.operand.toSource(), 'foo.bar');
+ expect(target.operator.lexeme, '!');
+ }
+
void test_nullCheckBeforeMethodCall() {
parseCompilationUnit('f() { var x = g!.m() + 7; }');
}
@@ -3119,21 +3035,6 @@
expect(target.operand.toSource(), "foo");
}
- void test_nullCheckBeforeIndex() {
- // https://github.com/dart-lang/sdk/issues/37708
- var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
- var funct = unit.declarations[0] as FunctionDeclaration;
- var body = funct.functionExpression.body as BlockFunctionBody;
- var statement = body.block.statements[0] as ExpressionStatement;
- var expression = statement.expression as IndexExpression;
- expect(expression.index.toSource(), 'arg');
- var propertyAccess = expression.target as PropertyAccess;
- expect(propertyAccess.propertyName.toSource(), 'baz');
- var target = propertyAccess.target as PostfixExpression;
- expect(target.operand.toSource(), 'foo.bar');
- expect(target.operator.lexeme, '!');
- }
-
void test_nullCheckOnLiteral_disabled() {
parseCompilationUnit('f() { var x = 0!; }',
errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
@@ -4356,3 +4257,130 @@
expect(declarationList.variables, hasLength(1));
}
}
+
+@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_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_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_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_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_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'));
+ }
+
+ 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_list_disabled() {
+ parseCompilationUnit('List<out String> stringList = [];',
+ errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+ ],
+ 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_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_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_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_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_typedef_enabled() {
+ parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 1ff1558..6b7c83e 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -222,7 +222,7 @@
if (token == null) {
return;
}
- Token previousToken = null;
+ Token previousToken;
int previousEnd = -1;
Token currentToken = token;
while (currentToken != null && currentToken.type != TokenType.EOF) {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index b1a5532..eb0cec2 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1212,8 +1212,8 @@
_assertHasPrevious(clone);
}
Token stopOriginalToken = originalNode.endToken.next;
- Token skipCloneComment = null;
- Token skipOriginalComment = null;
+ Token skipCloneComment;
+ Token skipOriginalComment;
while (original != stopOriginalToken) {
expect(clone, isNotNull);
_assertEqualToken(clone, original);
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 03fb7a6..cfe7454 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -65,7 +65,7 @@
* The path to the default SDK, or `null` if the test has not explicitly
* invoked [createDefaultSdk].
*/
- String defaultSdkPath = null;
+ String defaultSdkPath;
_MockLintRule _mockLintRule;
_MockLintRule _mockLintRule2;
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 46ac748..29aeeb5 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -26,7 +26,7 @@
* Finds an [Element] with the given [name].
*/
Element findChildElement(Element root, String name, [ElementKind kind]) {
- Element result = null;
+ Element result;
root.accept(new _ElementVisitorFunctionWrapper((Element element) {
if (element.name != name) {
return;
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index 7c00d1f..1e9c3fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -56,6 +56,7 @@
}
''', [
error(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
+ error(CompileTimeErrorCode.UNDEFINED_CLASS, 12, 0),
error(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
error(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 16, 1),
]);
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index e76fb1b..e9b17ee 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
@@ -316,6 +317,23 @@
validateBinaryExpression();
}
+ test_operator_onTearoff() async {
+ // https://github.com/dart-lang/sdk/issues/38653
+ await assertErrorsInCode('''
+f(){
+ E(null).v++;
+}
+extension E on Object{
+ v() {}
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 15, 1),
+ ]);
+ findDeclarationAndOverride(
+ declarationName: 'E ', overrideSearch: 'E(null)');
+ validateOverride();
+ }
+
test_operator_prefix_noTypeArguments() async {
newFile('/test/lib/lib.dart', content: '''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index c2520f8..c617a00 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -103,6 +103,7 @@
expect(value.getField('a').getField('f').toIntValue(), 42);
}
+ @FailingTest(reason: 'Reverted because of dartbug.com/38565')
test_sameLibrary_genericClass_constructor_unnamed() async {
await assertNoErrorsInCode(r'''
class A<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 9d2253f..97b6c70 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -36,7 +36,7 @@
// mismatch. Furthermore, the error message should mention both _A and the
// filenames so the user can figure out what's going on.
String message = result.errors[0].message;
- expect(message.indexOf("_A") >= 0, isTrue);
+ expect(message.contains("_A"), isTrue);
}
test_annotation_namedConstructor() async {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 6831be1..4418dfc 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -69,15 +69,17 @@
bool annotateNullability: false,
}) {
var writer = new _ElementWriter(
- withCodeRanges: withCodeRanges,
- withConstElements: withConstElements,
- withExportScope: withExportScope,
- withFullyResolvedAst: withFullyResolvedAst,
- withOffsets: withOffsets,
- withSyntheticAccessors: withSyntheticAccessors,
- withSyntheticFields: withSyntheticFields,
- withTypes: withTypes,
- annotateNullability: annotateNullability);
+ selfUriStr: '${library.source.uri}',
+ withCodeRanges: withCodeRanges,
+ withConstElements: withConstElements,
+ withExportScope: withExportScope,
+ withFullyResolvedAst: withFullyResolvedAst,
+ withOffsets: withOffsets,
+ withSyntheticAccessors: withSyntheticAccessors,
+ withSyntheticFields: withSyntheticFields,
+ withTypes: withTypes,
+ annotateNullability: annotateNullability,
+ );
writer.writeLibraryElement(library);
String actualText = writer.buffer.toString();
@@ -138,6 +140,7 @@
* Writes the canonical text presentation of elements.
*/
class _ElementWriter {
+ final String selfUriStr;
final bool withCodeRanges;
final bool withExportScope;
final bool withFullyResolvedAst;
@@ -149,16 +152,20 @@
final bool annotateNullability;
final StringBuffer buffer = new StringBuffer();
- _ElementWriter(
- {this.withCodeRanges,
- this.withConstElements: true,
- this.withExportScope: false,
- this.withFullyResolvedAst: false,
- this.withOffsets: false,
- this.withSyntheticAccessors: false,
- this.withSyntheticFields: false,
- this.withTypes: false,
- this.annotateNullability: false});
+ String indent = '';
+
+ _ElementWriter({
+ this.selfUriStr,
+ this.withCodeRanges,
+ this.withConstElements: true,
+ this.withExportScope: false,
+ this.withFullyResolvedAst: false,
+ this.withOffsets: false,
+ this.withSyntheticAccessors: false,
+ this.withSyntheticFields: false,
+ this.withTypes: false,
+ this.annotateNullability: false,
+ });
bool isDynamicType(DartType type) => type is DynamicTypeImpl;
@@ -226,25 +233,35 @@
buffer.writeln(' {');
- e.fields.forEach(writePropertyInducingElement);
- e.accessors.forEach(writePropertyAccessorElement);
+ _withIndent(() {
+ e.fields.forEach(writePropertyInducingElement);
+ e.accessors.forEach(writePropertyAccessorElement);
- if (e.isEnum) {
- expect(e.constructors, isEmpty);
- } else {
- expect(e.constructors, isNotEmpty);
- }
+ if (e.isEnum) {
+ expect(e.constructors, isEmpty);
+ } else {
+ expect(e.constructors, isNotEmpty);
+ }
- if (e.constructors.length == 1 &&
- e.constructors[0].isSynthetic &&
- e.mixins.isEmpty) {
- expect(e.constructors[0].parameters, isEmpty);
- } else {
- e.constructors.forEach(writeConstructorElement);
- }
+ if (e.constructors.length == 1 &&
+ e.constructors[0].isSynthetic &&
+ e.mixins.isEmpty) {
+ expect(e.constructors[0].parameters, isEmpty);
+ } else {
+ e.constructors.forEach(writeConstructorElement);
+ }
- e.methods.forEach(writeMethodElement);
+ e.methods.forEach(writeMethodElement);
+ });
+
buffer.writeln('}');
+
+ if (withFullyResolvedAst) {
+ _withIndent(() {
+ _writeResolvedMetadata(e.metadata);
+ _writeResolvedTypeParameters(e.typeParameters);
+ });
+ }
}
void writeCodeRange(Element e) {
@@ -292,16 +309,28 @@
}
}
- if (e is ConstructorElementImpl) {
- if (e.constantInitializers != null) {
- writeList(' : ', '', e.constantInitializers, ', ', writeNode);
+ var initializers = (e as ConstructorElementImpl).constantInitializers;
+ if (withFullyResolvedAst) {
+ buffer.writeln(';');
+ if (initializers != null && initializers.isNotEmpty) {
+ _withIndent(() {
+ _writelnWithIndent('constantInitializers');
+ _withIndent(() {
+ for (var initializer in initializers) {
+ _writeResolvedNode(initializer);
+ }
+ });
+ });
}
+ } else {
+ if (initializers != null) {
+ writeList(' : ', '', initializers, ', ', writeNode);
+ }
+ buffer.writeln(';');
}
expect(e.isAsynchronous, isFalse);
expect(e.isGenerator, isFalse);
-
- buffer.writeln(';');
}
void writeDocumentation(Element e, [String prefix = '']) {
@@ -355,10 +384,21 @@
}
buffer.writeln(' {');
- e.fields.forEach(writePropertyInducingElement);
- e.accessors.forEach(writePropertyAccessorElement);
- e.methods.forEach(writeMethodElement);
+
+ _withIndent(() {
+ e.fields.forEach(writePropertyInducingElement);
+ e.accessors.forEach(writePropertyAccessorElement);
+ e.methods.forEach(writeMethodElement);
+ });
+
buffer.writeln('}');
+
+ if (withFullyResolvedAst) {
+ _withIndent(() {
+ _writeResolvedMetadata(e.metadata);
+ _writeResolvedTypeParameters(e.typeParameters);
+ });
+ }
}
void writeFunctionElement(FunctionElement e) {
@@ -488,6 +528,10 @@
}
void writeMetadata(Element e, String prefix, String separator) {
+ if (withFullyResolvedAst) {
+ return;
+ }
+
if (e.metadata.isNotEmpty) {
writeList(prefix, '', e.metadata, '$separator$prefix', (a) {
writeNode((a as ElementAnnotationImpl).annotationAst);
@@ -520,6 +564,13 @@
} else {
buffer.writeln(' {}');
}
+
+ if (withFullyResolvedAst) {
+ _withIndent(() {
+ _writeResolvedTypeParameters(e.typeParameters);
+ _writeResolvedMetadata(e.metadata);
+ });
+ }
}
void writeName(Element e) {
@@ -540,14 +591,7 @@
}
}
- void writeNode(AstNode e, {String indent: '', Expression enclosing}) {
- if (withFullyResolvedAst) {
- buffer.writeln();
- var printer = ResolvedAstPrinter(buffer, indent);
- e.accept(printer);
- return;
- }
-
+ void writeNode(AstNode e, {Expression enclosing}) {
bool needsParenthesis = e is Expression &&
enclosing != null &&
e.precedence < enclosing.precedence;
@@ -961,25 +1005,35 @@
writeVariableTypeInferenceError(e);
- if (e is ConstVariableElement) {
- Expression initializer = (e as ConstVariableElement).constantInitializer;
- if (initializer != null) {
- buffer.write(' = ');
- writeNode(
- initializer,
- indent: ' ' * (e is FieldElement ? 4 : 2),
- );
- if (withFullyResolvedAst) {
- return;
+ if (withFullyResolvedAst) {
+ buffer.writeln(';');
+ _withIndent(() {
+ _writeResolvedMetadata(e.metadata);
+ if (e is ConstVariableElement) {
+ var initializer = (e as ConstVariableElement).constantInitializer;
+ if (initializer != null) {
+ _writelnWithIndent('constantInitializer');
+ _withIndent(() {
+ _writeResolvedNode(initializer);
+ });
+ }
+ }
+ });
+ } else {
+ if (e is ConstVariableElement) {
+ Expression initializer =
+ (e as ConstVariableElement).constantInitializer;
+ if (initializer != null) {
+ buffer.write(' = ');
+ writeNode(initializer);
}
}
+ buffer.writeln(';');
}
// TODO(scheglov) Paul: One of the things that was hardest to get right
// when resynthesizing the element model was the synthetic function for the
// initializer. Can we write that out (along with its return type)?
-
- buffer.writeln(';');
}
void writeType(DartType type) {
@@ -1047,7 +1101,9 @@
}
void writeTypeParameterElements(List<TypeParameterElement> elements) {
- writeList('<', '>', elements, ', ', writeTypeParameterElement);
+ if (!withFullyResolvedAst) {
+ writeList('<', '>', elements, ', ', writeTypeParameterElement);
+ }
}
void writeUnitElement(CompilationUnitElement e) {
@@ -1135,6 +1191,18 @@
return components.join(';');
}
+ void _withIndent(void Function() f) {
+ var indent = this.indent;
+ this.indent = '$indent ';
+ f();
+ this.indent = indent;
+ }
+
+ void _writelnWithIndent(String line) {
+ buffer.write(indent);
+ buffer.writeln(line);
+ }
+
bool _writeParameters(Iterable<ParameterElement> parameters, bool commaNeeded,
String prefix, String suffix) {
if (parameters.isEmpty) return commaNeeded;
@@ -1160,6 +1228,44 @@
buffer.write(suffix);
return commaNeeded;
}
+
+ void _writeResolvedMetadata(List<ElementAnnotation> metadata) {
+ if (metadata.isNotEmpty) {
+ _writelnWithIndent('metadata');
+ _withIndent(() {
+ for (ElementAnnotationImpl annotation in metadata) {
+ _writeResolvedNode(annotation.annotationAst);
+ }
+ });
+ }
+ }
+
+ void _writeResolvedNode(AstNode node) {
+ buffer.write(indent);
+ node.accept(
+ ResolvedAstPrinter(
+ selfUriStr: selfUriStr,
+ sink: buffer,
+ indent: indent,
+ ),
+ );
+ }
+
+ void _writeResolvedTypeParameters(List<TypeParameterElement> elements) {
+ if (elements.isNotEmpty) {
+ _writelnWithIndent('typeParameters');
+ _withIndent(() {
+ for (TypeParameterElementImpl e in elements) {
+ _writelnWithIndent(e.name);
+ _withIndent(() {
+ _writelnWithIndent('bound: ${e.bound}');
+ _writelnWithIndent('defaultType: ${e.defaultType}');
+ _writeResolvedMetadata(e.metadata);
+ });
+ }
+ });
+ }
+ }
}
class _Replacement {
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 551cad1..93a5e30 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -4,26 +4,77 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
/// Prints AST as a tree, with properties and children.
class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
- StringSink _sink;
+ final String _selfUriStr;
+ final StringSink _sink;
String _indent = '';
- ResolvedAstPrinter(StringSink sink, String indent)
- : _sink = sink,
+ ResolvedAstPrinter({
+ @required String selfUriStr,
+ @required StringSink sink,
+ @required String indent,
+ }) : _selfUriStr = selfUriStr,
+ _sink = sink,
_indent = indent;
@override
+ void visitAnnotation(Annotation node) {
+ _writeln('Annotation');
+ _withIndent(() {
+ _writeNode('arguments', node.arguments);
+ _writeNode('constructorName', node.constructorName);
+ _writeElement('element', node.element);
+ _writeNode('name', node.name);
+ });
+ }
+
+ @override
+ void visitArgumentList(ArgumentList node) {
+ _writeln('ArgumentList');
+ _withIndent(() {
+ _writeNodeList('arguments', node.arguments);
+ });
+ }
+
+ @override
void visitCompilationUnit(CompilationUnit node) {
super.visitCompilationUnit(node);
}
@override
- void visitIntegerLiteral(IntegerLiteral node) {
- _writeln('IntegerLiteral(${node.literal.lexeme})');
+ void visitConstructorName(ConstructorName node) {
+ _writeln('ConstructorName');
_withIndent(() {
- _writeln2('staticType: ', node.staticType);
+ _writeNode('name', node.name);
+ _writeNode('type', node.type);
+ });
+ }
+
+ @override
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
+ _writeln('InstanceCreationExpression');
+ _withIndent(() {
+ _writeNode('argumentList', node.argumentList);
+ _writeNode('constructorName', node.constructorName);
+ _writeElement('staticElement', node.staticElement);
+ _writeType('staticType', node.staticType);
+ });
+ }
+
+ @override
+ void visitIntegerLiteral(IntegerLiteral node) {
+ _writeln('IntegerLiteral');
+ _withIndent(() {
+ _writelnWithIndent('literal: ${node.literal}');
+ _writeType('staticType', node.staticType);
});
}
@@ -31,13 +82,74 @@
void visitListLiteral(ListLiteral node) {
_writeln('ListLiteral');
_withIndent(() {
- _writeln2('isConst: ', node.isConst);
- _writeln2('staticType: ', node.staticType);
- _writeTypeArgumentList('typeArguments', node.typeArguments);
_writeNodeList('elements', node.elements);
+ _writeType('staticType', node.staticType);
+ _writeNode('typeArguments', node.typeArguments);
});
}
+ @override
+ void visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node,
+ ) {
+ _writeln('RedirectingConstructorInvocation');
+ _withIndent(() {
+ _writeNode('argumentList', node.argumentList);
+ _writeNode('constructorName', node.constructorName);
+ _writeElement('staticElement', node.staticElement);
+ });
+ }
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ _writeln('SimpleIdentifier');
+ _withIndent(() {
+ _writeAuxiliaryElements('auxiliaryElements', node.auxiliaryElements);
+ _writeElement('staticElement', node.staticElement);
+ _writeType('staticType', node.staticType);
+ _writelnWithIndent('token: ${node.token}');
+ });
+ }
+
+ @override
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ _writeln('SuperConstructorInvocation');
+ _withIndent(() {
+ _writeNode('argumentList', node.argumentList);
+ _writeNode('constructorName', node.constructorName);
+ _writeElement('staticElement', node.staticElement);
+ });
+ }
+
+ @override
+ void visitTypeName(TypeName node) {
+ _writeln('TypeName');
+ _withIndent(() {
+ _writeNode('name', node.name);
+ _writeType('type', node.type);
+ _writeNode('typeArguments', node.typeArguments);
+ });
+ }
+
+ String _referenceToString(Reference reference) {
+ if (reference.parent.name == '@unit') {
+ var libraryUriStr = reference.parent.parent.name;
+ if (libraryUriStr == _selfUriStr) {
+ return 'self';
+ }
+ return libraryUriStr;
+ }
+
+ var name = reference.name;
+ if (name.startsWith('@')) {
+ return _referenceToString(reference.parent);
+ }
+ if (name.isEmpty) {
+ name = '•';
+ }
+ return _referenceToString(reference.parent) + '::$name';
+ }
+
void _withIndent(void Function() f) {
var indent = _indent;
_indent = '$_indent ';
@@ -45,32 +157,64 @@
_indent = indent;
}
+ void _writeAuxiliaryElements(String name, AuxiliaryElements elements) {
+ if (elements != null) {
+ throw UnimplementedError();
+ }
+ }
+
+ void _writeElement(String name, Element element) {
+ _sink.write(_indent);
+ _sink.write('$name: ');
+ if (element == null) {
+ _sink.writeln('<null>');
+ } else if (element is Member) {
+ _sink.writeln(_nameOfMemberClass(element));
+ _withIndent(() {
+ _writeElement('base', element.baseElement);
+ _writelnWithIndent('substitution: ${element.substitution.map}');
+ });
+ } else {
+ var reference = (element as ElementImpl).reference;
+ var referenceStr = _referenceToString(reference);
+ _sink.writeln(referenceStr);
+ }
+ }
+
void _writeln(String line) {
- _sink.write('$_indent');
_sink.writeln(line);
}
- void _writeln2(String prefix, Object o) {
- _sink.write('$_indent');
- _sink.write(prefix);
- _sink.writeln(o);
+ void _writelnWithIndent(String line) {
+ _sink.write(_indent);
+ _sink.writeln(line);
+ }
+
+ void _writeNode(String name, AstNode node) {
+ if (node != null) {
+ _sink.write(_indent);
+ _sink.write('$name: ');
+ node.accept(this);
+ }
}
void _writeNodeList(String name, NodeList nodeList) {
if (nodeList.isNotEmpty) {
- _writeln(name);
+ _writelnWithIndent(name);
_withIndent(() {
- nodeList.accept(this);
+ for (var node in nodeList) {
+ _sink.write(_indent);
+ node.accept(this);
+ }
});
}
}
- void _writeTypeArgumentList(String name, TypeArgumentList node) {
- if (node != null) {
- _writeln(name);
- _withIndent(() {
- node.arguments?.accept(this);
- });
- }
+ void _writeType(String name, DartType type) {
+ _writelnWithIndent('$name: $type');
+ }
+
+ static String _nameOfMemberClass(Member member) {
+ return '${member.runtimeType}';
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 6785245..618e653 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -33,9 +33,6 @@
/// The shared SDK bundle, computed once and shared among test invocations.
static LinkedNodeBundle _sdkBundle;
- @override
- bool get isAstBasedSummary => true;
-
LinkedNodeBundle get sdkBundle {
if (_sdkBundle != null) return _sdkBundle;
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 86a1ada..54294ea 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1256,21 +1256,12 @@
class C<T extends D> {}
class D<T extends C> {}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
notSimplyBounded class C<T extends D<dynamic>> {
}
notSimplyBounded class D<T extends C<dynamic>> {
}
''');
- } else {
- checkElementText(library, r'''
-notSimplyBounded class C<T extends D<dynamic>> {
-}
-notSimplyBounded class D<T extends C<D<dynamic>>> {
-}
-''');
- }
}
test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
@@ -1353,21 +1344,12 @@
typedef F(G value);
typedef G(F value);
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(dynamic)) value);
notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic) value);
notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic Function(dynamic)))> {
}
''');
- } else {
- checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded class C<T extends dynamic Function(dynamic Function(...))> {
-}
-''');
- }
}
test_class_notSimplyBounded_self() async {
@@ -2574,10 +2556,9 @@
P2<int>(),
];
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
class P<T> {
const P();
}
@@ -2592,27 +2573,7 @@
P2/*location: test.dart;P2*/<
int/*location: dart:core;int*/>()];
''',
- withTypes: true);
- } else {
- checkElementText(
- library,
- '''
-class P<T> {
- const P();
-}
-class P1<T> extends P<T> {
- const P1();
-}
-class P2<T> extends P<T> {
- const P2();
-}
-const List<P<dynamic>> values = const /*typeArgs=dynamic*/[const /*typeArgs=dynamic*/
- P1/*location: test.dart;P1*/(), const
- P2/*location: test.dart;P2*/<
- int/*location: dart:core;int*/>()];
-''',
- withTypes: true);
- }
+ withTypes: true);
}
test_const_invalid_field_const() async {
@@ -2728,8 +2689,7 @@
import 'a.dart' as p;
const V = const p.C<int, String>.named(1, '222');
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const C<int, String> V = const
p/*location: test.dart;p*/.
@@ -2738,16 +2698,6 @@
String/*location: dart:core;String*/>.
named/*location: a.dart;C;named*/(1, '222');
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
- C/*location: a.dart;C*/<
- int/*location: dart:core;int*/,
- String/*location: dart:core;String*/>.
- named/*location: a.dart;C;named*/(1, '222');
-''');
- }
}
test_const_invokeConstructor_generic_noTypeArguments() async {
@@ -2813,8 +2763,7 @@
import 'a.dart' as p;
const V = const p.C<int, String>();
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const C<int, String> V = const
p/*location: test.dart;p*/.
@@ -2822,15 +2771,6 @@
int/*location: dart:core;int*/,
String/*location: dart:core;String*/>();
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
- C/*location: a.dart;C*/<
- int/*location: dart:core;int*/,
- String/*location: dart:core;String*/>();
-''');
- }
}
test_const_invokeConstructor_named() async {
@@ -2840,8 +2780,7 @@
}
const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
const C.named(bool a, int b, int c, {String d}, {double e});
}
@@ -2851,18 +2790,6 @@
d/*location: test.dart;C;named;d*/: 'ccc',
e/*location: test.dart;C;named;e*/: 3.4);
''');
- } else {
- checkElementText(library, r'''
-class C {
- const C.named(bool a, int b, int c, {String d}, {double e});
-}
-const C V = const
- C/*location: test.dart;C*/.
- named/*location: test.dart;C;named*/(true, 1, 2,
- d/*location: null*/: 'ccc',
- e/*location: null*/: 3.4);
-''');
- }
}
test_const_invokeConstructor_named_imported() async {
@@ -2893,22 +2820,13 @@
import 'a.dart' as p;
const V = const p.C.named();
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
named/*location: a.dart;C;named*/();
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
- C/*location: a.dart;C*/.
- named/*location: a.dart;C;named*/();
-''');
- }
}
test_const_invokeConstructor_named_unresolved() async {
@@ -2916,23 +2834,13 @@
class C {}
const V = const C.named();
''', allowErrors: true);
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
}
const C V = const
C/*location: test.dart;C*/.
named/*location: null*/();
''');
- } else {
- checkElementText(library, r'''
-class C {
-}
-const dynamic V = const
- C/*location: test.dart;C*/.
- named/*location: null*/();
-''');
- }
}
test_const_invokeConstructor_named_unresolved2() async {
@@ -2955,23 +2863,13 @@
import 'a.dart' as p;
const V = const p.C.named();
''', allowErrors: true);
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/.
named/*location: null*/();
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
- p/*location: test.dart;p*/.
- C/*location: a.dart;C*/.
- named/*location: null*/();
-''');
- }
}
test_const_invokeConstructor_named_unresolved4() async {
@@ -3006,23 +2904,13 @@
class C<T> {}
const V = const C.named();
''', allowErrors: true);
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C<T> {
}
const C<dynamic> V = const
C/*location: test.dart;C*/.
named/*location: null*/();
''');
- } else {
- checkElementText(library, r'''
-class C<T> {
-}
-const dynamic V = const
- C/*location: test.dart;C*/.
- named/*location: null*/();
-''');
- }
}
test_const_invokeConstructor_unnamed() async {
@@ -3068,20 +2956,12 @@
import 'a.dart' as p;
const V = const p.C();
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const C V = const
p/*location: test.dart;p*/.
C/*location: a.dart;C*/();
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
- C/*location: a.dart;C*/();
-''');
- }
}
test_const_invokeConstructor_unnamed_unresolved() async {
@@ -3282,63 +3162,40 @@
var library = await checkLibrary('''
const Object x = const [1];
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const /*typeArgs=int*/[1];
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>[1];
-''');
- }
+ withTypes: true);
}
test_const_list_spread() async {
var library = await checkLibrary('''
const Object x = const <int>[...<int>[1]];
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/>[...<
int/*location: dart:core;int*/>[1]];
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>[...const <
- int/*location: dart:core;int*/>[1]];
-''');
- }
+ withTypes: true);
}
test_const_list_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int>[...?<int>[1]];
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/>[...?<
int/*location: dart:core;int*/>[1]];
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>[...?const <
- int/*location: dart:core;int*/>[1]];
-''');
- }
+ withTypes: true);
}
test_const_map_if() async {
@@ -3376,72 +3233,44 @@
var library = await checkLibrary('''
const Object x = const {1: 1.0};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const /*typeArgs=int,double*/{1: 1.0}/*isMap*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/,
- double/*location: dart:core;double*/>{1: 1.0}/*isMap*/;
-''');
- }
+ withTypes: true);
}
test_const_map_spread() async {
var library = await checkLibrary('''
const Object x = const <int, int>{...<int, int>{1: 2}};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{...<
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/,
- int/*location: dart:core;int*/>{...const <
- int/*location: dart:core;int*/,
- int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
- }
+ withTypes: true);
}
test_const_map_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int, int>{...?<int, int>{1: 2}};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{...?<
int/*location: dart:core;int*/,
int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/,
- int/*location: dart:core;int*/>{...?const <
- int/*location: dart:core;int*/,
- int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
- }
+ withTypes: true);
}
test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
@@ -3938,63 +3767,40 @@
var library = await checkLibrary('''
const Object x = const {1};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const /*typeArgs=int*/{1}/*isSet*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>{1}/*isSet*/;
-''');
- }
+ withTypes: true);
}
test_const_set_spread() async {
var library = await checkLibrary('''
const Object x = const <int>{...<int>{1}};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/>{...<
int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>{...const <
- int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
- }
+ withTypes: true);
}
test_const_set_spread_null_aware() async {
var library = await checkLibrary('''
const Object x = const <int>{...?<int>{1}};
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- '''
+ checkElementText(
+ library,
+ '''
const Object x = const <
int/*location: dart:core;int*/>{...?<
int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
''',
- withTypes: true);
- } else {
- checkElementText(library, '''
-const Object x = const <
- int/*location: dart:core;int*/>{...?const <
- int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
- }
+ withTypes: true);
}
test_const_topLevel_binary() async {
@@ -4044,30 +3850,18 @@
var library = await checkLibrary(r'''
const vConditional = (1 == 2) ? 11 : 22;
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
const int vConditional = (1 == 2) ? 11 : 22;
''');
- } else {
- checkElementText(library, r'''
-const int vConditional = 1 == 2 ? 11 : 22;
-''');
- }
}
test_const_topLevel_identical() async {
var library = await checkLibrary(r'''
const vIdentical = (1 == 2) ? 11 : 22;
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
const int vIdentical = (1 == 2) ? 11 : 22;
''');
- } else {
- checkElementText(library, r'''
-const int vIdentical = 1 == 2 ? 11 : 22;
-''');
- }
}
test_const_topLevel_ifNull() async {
@@ -4159,16 +3953,9 @@
var library = await checkLibrary(r'''
const c = throw 42;
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
const dynamic c = throw 42;
''');
- } else {
- // This is a bug.
- checkElementText(library, r'''
-const dynamic c;
-''');
- }
}
test_const_topLevel_typedList() async {
@@ -4219,20 +4006,12 @@
import 'a.dart' as p;
const v = const <p.C>[];
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'a.dart' as p;
const List<C> v = const <
p/*location: test.dart;p*/.
C/*location: a.dart;C*/>[];
''');
- } else {
- checkElementText(library, r'''
-import 'a.dart' as p;
-const List<C> v = const <
- C/*location: a.dart;C*/>[];
-''');
- }
}
test_const_topLevel_typedList_typedefArgument() async {
@@ -4240,21 +4019,11 @@
typedef int F(String id);
const v = const <F>[];
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
typedef F = int Function(String id);
const List<int Function(String)> v = const <
F/*location: test.dart;F*/>[];
''');
- } else {
- // This is wrong.
- // `F` must be the reference to `typedef F` element, not the type.
- checkElementText(library, r'''
-typedef F = int Function(String id);
-const List<int Function(String)> v = const <
- null/*location: test.dart;F;-*/>[];
-''');
- }
}
test_const_topLevel_typedMap() async {
@@ -4370,24 +4139,13 @@
static const b = null;
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
static const dynamic a =
b/*location: test.dart;C;b?*/;
static const dynamic b = null;
}
''');
- } else {
- checkElementText(library, r'''
-class C {
- static const dynamic a =
- C/*location: test.dart;C*/.
- b/*location: test.dart;C;b?*/;
- static const dynamic b = null;
-}
-''');
- }
}
test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
@@ -4397,24 +4155,13 @@
static m() {}
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
static const dynamic Function() a =
m/*location: test.dart;C;m*/;
static dynamic m() {}
}
''');
- } else {
- checkElementText(library, r'''
-class C {
- static const dynamic Function() a =
- C/*location: test.dart;C*/.
- m/*location: test.dart;C;m*/;
- static dynamic m() {}
-}
-''');
- }
}
test_constructor_documented() async {
@@ -4527,8 +4274,7 @@
: this(A<Function()>());
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class A<T> {
const A();
}
@@ -4538,7 +4284,35 @@
A/*location: test.dart;A*/<Function()>());
}
''');
- }
+ }
+
+ test_constructor_initializers_superInvocation_argumentContextType() async {
+ var library = await checkLibrary('''
+class A {
+ const A(List<String> values);
+}
+class B extends A {
+ const B() : super(const []);
+}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A(List<String> values);
+}
+class B extends A {
+ const B();
+ constantInitializers
+ SuperConstructorInvocation
+ argumentList: ArgumentList
+ arguments
+ ListLiteral
+ staticType: List<String>
+ staticElement: self::A::•
+}
+''',
+ withFullyResolvedAst: true);
}
test_constructor_initializers_superInvocation_named() async {
@@ -4590,8 +4364,7 @@
const C() : super.aaa(1, b: 2);
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class A {
const A.aaa(dynamic a, {int b});
}
@@ -4601,18 +4374,6 @@
b/*location: test.dart;A;aaa;b*/: 2);
}
''');
- } else {
- checkElementText(library, r'''
-class A {
- const A.aaa(dynamic a, {int b});
-}
-class C extends A {
- const C() : super.
- aaa/*location: test.dart;A;aaa*/(1,
- b/*location: null*/: 2);
-}
-''');
- }
}
test_constructor_initializers_superInvocation_unnamed() async {
@@ -4634,6 +4395,31 @@
''');
}
+ test_constructor_initializers_thisInvocation_argumentContextType() async {
+ var library = await checkLibrary('''
+class A {
+ const A(List<String> values);
+ const A.empty() : this(const []);
+}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A(List<String> values);
+ const A.empty() = A;
+ constantInitializers
+ RedirectingConstructorInvocation
+ argumentList: ArgumentList
+ arguments
+ ListLiteral
+ staticType: List<String>
+ staticElement: self::A::•
+}
+''',
+ withFullyResolvedAst: true);
+ }
+
test_constructor_initializers_thisInvocation_named() async {
var library = await checkLibrary('''
class C {
@@ -4657,8 +4443,7 @@
const C.named(a, {int b});
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
const C() = C.named : this.
named/*location: test.dart;C;named*/(1,
@@ -4666,16 +4451,6 @@
const C.named(dynamic a, {int b});
}
''');
- } else {
- checkElementText(library, r'''
-class C {
- const C() = C.named : this.
- named/*location: test.dart;C;named*/(1,
- b/*location: null*/: 2);
- const C.named(dynamic a, {int b});
-}
-''');
- }
}
test_constructor_initializers_thisInvocation_unnamed() async {
@@ -5042,21 +4817,12 @@
C() : this.named();
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
C.named();
C();
}
''');
- } else {
- checkElementText(library, r'''
-class C {
- C.named();
- C() = C.named;
-}
-''');
- }
}
test_constructor_redirected_thisInvocation_unnamed() async {
@@ -5096,21 +4862,12 @@
C.named() : this();
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
C();
C.named();
}
''');
- } else {
- checkElementText(library, r'''
-class C {
- C();
- C.named() = C;
-}
-''');
- }
}
test_constructor_withCycles_const() async {
@@ -5194,8 +4951,7 @@
void foo({a: const A<Function()>()}) {}
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class A<T> {
const A();
}
@@ -5204,7 +4960,6 @@
A/*location: test.dart;A*/<Function()>()}) {}
}
''');
- }
}
test_defaultValue_refersToExtension_method_inside() async {
@@ -5259,10 +5014,9 @@
const C([B<T> b = const B()]);
}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
class B<T> {
const B();
}
@@ -5271,18 +5025,7 @@
B/*location: test.dart;B*/()]);
}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-class B<T> {
- const B();
-}
-class C<T> {
- const C([B<T> b = const
- B/*location: test.dart;B*/()]);
-}
-''');
- }
+ withTypes: true);
}
test_defaultValue_refersToGenericClass_constructor2() async {
@@ -5295,10 +5038,9 @@
const C([A<T> a = const B()]);
}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
abstract class A<T> {
}
class B<T> implements A<T> {
@@ -5309,20 +5051,7 @@
B/*location: test.dart;B*/()]);
}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-abstract class A<T> {
-}
-class B<T> implements A<T> {
- const B();
-}
-class C<T> implements A<Iterable<T>> {
- const C([A<T> a = const
- B/*location: test.dart;B*/()]);
-}
-''');
- }
+ withTypes: true);
}
test_defaultValue_refersToGenericClass_functionG() async {
@@ -5332,26 +5061,16 @@
}
void foo<T>([B<T> b = const B()]) {}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
class B<T> {
const B();
}
void foo<T>([B<T> b = const /*typeArgs=Null*/
B/*location: test.dart;B*/()]) {}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-class B<T> {
- const B();
-}
-void foo<T>([B<T> b = const
- B/*location: test.dart;B*/()]) {}
-''');
- }
+ withTypes: true);
}
test_defaultValue_refersToGenericClass_methodG() async {
@@ -5363,10 +5082,9 @@
void foo<T>([B<T> b = const B()]) {}
}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
class B<T> {
const B();
}
@@ -5375,18 +5093,7 @@
B/*location: test.dart;B*/()]) {}
}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-class B<T> {
- const B();
-}
-class C {
- void foo<T>([B<T> b = const
- B/*location: test.dart;B*/()]) {}
-}
-''');
- }
+ withTypes: true);
}
test_defaultValue_refersToGenericClass_methodG_classG() async {
@@ -5398,10 +5105,9 @@
void foo<E2>([B<E1, E2> b = const B()]) {}
}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
class B<T1, T2> {
const B();
}
@@ -5410,18 +5116,7 @@
B/*location: test.dart;B*/()]) {}
}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-class B<T1, T2> {
- const B();
-}
-class C<E1> {
- void foo<E2>([B<E1, E2> b = const
- B/*location: test.dart;B*/()]) {}
-}
-''');
- }
+ withTypes: true);
}
test_defaultValue_refersToGenericClass_methodNG() async {
@@ -5433,10 +5128,9 @@
void foo([B<T> b = const B()]) {}
}
''');
- if (isAstBasedSummary) {
- checkElementText(
- library,
- r'''
+ checkElementText(
+ library,
+ r'''
class B<T> {
const B();
}
@@ -5445,18 +5139,7 @@
B/*location: test.dart;B*/()]) {}
}
''',
- withTypes: true);
- } else {
- checkElementText(library, r'''
-class B<T> {
- const B();
-}
-class C<T> {
- void foo([B<T> b = const
- B/*location: test.dart;B*/()]) {}
-}
-''');
- }
+ withTypes: true);
}
test_duplicateDeclaration_class() async {
@@ -6234,8 +5917,7 @@
const B();
}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class A<T> {
const A();
}
@@ -6247,7 +5929,6 @@
const B();
}
''');
- }
}
test_field_final_hasInitializer_noConstConstructor() async {
@@ -6431,10 +6112,10 @@
library,
r'''
class C1 {
- final List<int> f1 =
- ListLiteral
- isConst: true
- staticType: List<int>
+ final List<int> f1;
+ constantInitializer
+ ListLiteral
+ staticType: List<int>
const C1();
}
class C2 {
@@ -6832,15 +6513,9 @@
var library = await checkLibrary('''
typedef F<X extends F> = Function(F);
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
notSimplyBounded typedef F<X> = dynamic Function();
''');
- } else {
- checkElementText(library, r'''
-notSimplyBounded typedef F<X extends dynamic Function(...)> = dynamic Function(dynamic Function(...) );
-''');
- }
}
test_getter_documented() async {
@@ -6894,8 +6569,7 @@
}
const x = C.named(42);
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
class C {
final Object x;
const C.named(Object this.x);
@@ -6904,17 +6578,6 @@
C/*location: test.dart;C*/.
named/*location: test.dart;C;named*/(42);
''');
- } else {
- checkElementText(library, r'''
-class C {
- final Object x;
- const C.named(Object this.x);
-}
-const C x = const
- C/*location: test.dart;C*/.
- named/*location: test.dart;C;named*/(42);
-''');
- }
}
test_implicitTopLevelVariable_getterFirst() async {
@@ -8047,19 +7710,11 @@
import 'c.dart';
foo([p = V]) {}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'c.dart';
dynamic foo([dynamic p =
V/*location: a.dart;V*/]) {}
''');
- } else {
- checkElementText(library, r'''
-import 'c.dart';
-dynamic foo([dynamic p =
- V/*location: null*/]) {}
-''');
- }
}
test_invalid_nameConflict_local() async {
@@ -8068,21 +7723,12 @@
V() {}
var V;
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
dynamic V;
dynamic foo([dynamic p =
V/*location: test.dart;V?*/]) {}
dynamic V() {}
''');
- } else {
- checkElementText(library, r'''
-dynamic V;
-dynamic foo([dynamic p =
- V/*location: null*/]) {}
-dynamic V() {}
-''');
- }
}
test_invalid_setterParameter_fieldFormalParameter() async {
@@ -8459,6 +8105,62 @@
''');
}
+ test_metadata_class_scope() async {
+ var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+class C<@foo T> {
+ static const foo = 1;
+ @foo
+ void bar() {}
+}
+''');
+ checkElementText(
+ library,
+ r'''
+class C {
+ static const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 1
+ staticType: int
+ void bar() {}
+ metadata
+ Annotation
+ element: self::C::foo
+ name: SimpleIdentifier
+ staticElement: self::C::foo
+ staticType: int
+ token: foo
+}
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ withFullyResolvedAst: true);
+ }
+
test_metadata_classDeclaration() async {
var library = await checkLibrary(r'''
const a = null;
@@ -8522,8 +8224,7 @@
@foo.A.named()
class C {}
''');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'foo.dart' as foo;
@
foo/*location: test.dart;foo*/.
@@ -8532,16 +8233,6 @@
class C {
}
''');
- } else {
- checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
- A/*location: foo.dart;A*/.
- named/*location: foo.dart;A;named*/()
-class C {
-}
-''');
- }
}
test_metadata_constructor_call_unnamed() async {
@@ -8561,8 +8252,7 @@
addLibrarySource('/foo.dart', 'class A { const A(); }');
var library =
await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
import 'foo.dart' as foo;
@
foo/*location: test.dart;foo*/.
@@ -8570,15 +8260,6 @@
class C {
}
''');
- } else {
- checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
- A/*location: foo.dart;A*/()
-class C {
-}
-''');
- }
}
test_metadata_constructor_call_with_args() async {
@@ -8661,6 +8342,63 @@
''');
}
+ test_metadata_extension_scope() async {
+ featureSet = enableExtensionMethods;
+ var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+extension E<@foo T> on int {
+ static const foo = 1;
+ @foo
+ void bar() {}
+}
+''');
+ checkElementText(
+ library,
+ r'''
+extension E on int {
+ static const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 1
+ staticType: int
+ void bar() {}
+ metadata
+ Annotation
+ element: self::E::foo
+ name: SimpleIdentifier
+ staticElement: self::E::foo
+ staticType: int
+ token: foo
+}
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+ typeParameters
+ T
+ bound: null
+ defaultType: null
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ withFullyResolvedAst: true);
+ }
+
test_metadata_extensionDeclaration() async {
featureSet = enableExtensionMethods;
var library = await checkLibrary(r'''
@@ -8819,23 +8557,13 @@
test_metadata_invalid_classDeclaration() async {
var library = await checkLibrary('f(_) {} @f(42) class C {}');
- if (isAstBasedSummary) {
- checkElementText(library, r'''
+ checkElementText(library, r'''
@
f/*location: test.dart;f*/(42)
class C {
}
dynamic f(dynamic _) {}
''');
- } else {
- checkElementText(library, r'''
-@
- __unresolved__/*location: null*/
-class C {
-}
-dynamic f(dynamic _) {}
-''');
- }
}
test_metadata_libraryDirective() async {
@@ -8925,6 +8653,62 @@
''');
}
+ test_metadata_mixin_scope() async {
+ var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+mixin M<@foo T> {
+ static const foo = 1;
+ @foo
+ void bar() {}
+}
+''');
+ checkElementText(
+ library,
+ r'''
+mixin M on Object {
+ static const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 1
+ staticType: int
+ void bar() {}
+ metadata
+ Annotation
+ element: self::M::foo
+ name: SimpleIdentifier
+ staticElement: self::M::foo
+ staticType: int
+ token: foo
+}
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+ metadata
+ Annotation
+ element: self::foo
+ name: SimpleIdentifier
+ staticElement: self::foo
+ staticType: int
+ token: foo
+const int foo;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ withFullyResolvedAst: true);
+ }
+
test_metadata_mixinDeclaration() async {
var library = await checkLibrary(r'''
const a = null;
@@ -10107,25 +9891,15 @@
var a = A(() => b);
var b = A(() => a);
''');
- if (isAstBasedSummary) {
- // There is no cycle with `a` and `b`, because `A` is not generic,
- // so the type of `new A(...)` does not depend on its arguments.
- checkElementText(library, '''
+ // There is no cycle with `a` and `b`, because `A` is not generic,
+ // so the type of `new A(...)` does not depend on its arguments.
+ checkElementText(library, '''
class A {
A(dynamic _);
}
A a;
A b;
''');
- } else {
- checkElementText(library, '''
-class A {
- A(dynamic _);
-}
-dynamic a/*error: dependencyCycle*/;
-dynamic b/*error: dependencyCycle*/;
-''');
- }
}
test_type_inference_multiplyDefinedElement() async {
@@ -11416,6 +11190,42 @@
''');
}
+ test_variableInitializer_contextType_after_astRewrite() async {
+ var library = await checkLibrary(r'''
+class A<T> {
+ const A();
+}
+const A<int> a = A();
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A();
+}
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+const A<int> a;
+ constantInitializer
+ InstanceCreationExpression
+ argumentList: ArgumentList
+ constructorName: ConstructorName
+ type: TypeName
+ name: SimpleIdentifier
+ staticElement: self::A
+ staticType: A<dynamic>
+ token: A
+ type: A<int>
+ staticElement: ConstructorMember
+ base: self::A::•
+ substitution: {T: int}
+ staticType: A<int>
+''',
+ withFullyResolvedAst: true);
+ }
+
test_variables() async {
var library = await checkLibrary('int i; int j;');
checkElementText(library, r'''
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 83e49ed..0fc7bdc 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -54,8 +54,6 @@
set declaredVariables(DeclaredVariables declaredVariables);
- bool get isAstBasedSummary => false;
-
MemoryResourceProvider get resourceProvider;
void set testFile(String value);
@@ -84,9 +82,6 @@
<String, UnlinkedUnitBuilder>{};
PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
-
- @override
- bool get isAstBasedSummary => false;
}
/// [SerializedMockSdk] is a singleton class representing the result of
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 2158740..36d5eb0 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -3394,9 +3394,7 @@
}
test_inferTypesOnGenericInstantiationsInLibraryCycle() async {
- // Note: this is a regression test for a non-deterministic behavior we used to
- // have with inference in library cycles. If you see this test flake out,
- // change `test` to `skip_test` and reopen bug #48.
+ // Note: this is a regression test for bug #48.
addFile('''
import 'main.dart';
abstract class I<E> {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 0a8d7ee..fc52165 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -224,7 +224,7 @@
class AbstractStrongTest with ResourceProviderMixin {
bool _checkCalled = true;
- AnalysisDriver _driver = null;
+ AnalysisDriver _driver;
Map<String, List<Folder>> packageMap;
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index b881193..e829ba7 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -120,9 +120,6 @@
} else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
_reportProblem('More than one error range in example');
}
- if (snippet.indexOf('extension') >= 0) {
- DateTime.now();
- }
return _SnippetData(
snippet.substring(0, rangeStart) +
snippet.substring(rangeStart + errorRangeStart.length, rangeEnd) +
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 7f51a0d..c5f56bf 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -73,7 +73,7 @@
List<CodePath> paths = [];
for (int i = 0; i < documentationPaths.length; i++) {
String docPath = pathContext.joinAll(documentationPaths[i]);
- String declPath = null;
+ String declPath;
if (declarationPaths[i] != null) {
declPath = pathContext.joinAll(declarationPaths[i]);
}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 8e9c085..7e9a695 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -218,6 +218,8 @@
/// Returns `true` if [element] is a superclass of `List`.
bool isListSupertype(ClassEntity element);
+ InterfaceType getConstantListTypeFor(InterfaceType sourceType);
+
InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
{bool hasProtoKey: false, bool onlyStringKeys: false});
@@ -1016,6 +1018,12 @@
}
@override
+ InterfaceType getConstantListTypeFor(InterfaceType sourceType) =>
+ sourceType.treatAsRaw
+ ? _env.getRawType(jsArrayClass)
+ : _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
+
+ @override
InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
{bool hasProtoKey: false, bool onlyStringKeys: false}) {
ClassEntity classElement = onlyStringKeys
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 47aa5ed..566c2b9 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -87,8 +87,12 @@
new StringConstantValue(string);
BoolConstantValue createBool(bool value) => new BoolConstantValue(value);
NullConstantValue createNull() => new NullConstantValue();
-ListConstantValue createList(InterfaceType type, List<ConstantValue> values) =>
- new ListConstantValue(type, values);
+
+ListConstantValue createList(CommonElements commonElements,
+ InterfaceType sourceType, List<ConstantValue> values) {
+ InterfaceType type = commonElements.getConstantListTypeFor(sourceType);
+ return ListConstantValue(type, values);
+}
ConstantValue createType(CommonElements commonElements, DartType type) {
InterfaceType instanceType = commonElements.typeLiteralType;
@@ -174,7 +178,7 @@
} else {
keysType = commonElements.listType(sourceType.typeArguments.first);
}
- ListConstantValue keysList = new ListConstantValue(keysType, keys);
+ ListConstantValue keysList = createList(commonElements, keysType, keys);
InterfaceType type = commonElements.getConstantMapTypeFor(sourceType,
hasProtoKey: hasProtoKey, onlyStringKeys: onlyStringKeys);
return new JavaScriptMapConstant(
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 61be000..095bec3 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -375,8 +375,8 @@
@override
ConstantValue evaluate(EvaluationEnvironment environment) {
- return constant_system.createList(
- type, values.map((v) => v.evaluate(environment)).toList());
+ return constant_system.createList(environment.commonElements, type,
+ values.map((v) => v.evaluate(environment)).toList());
}
@override
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 6ff3566..3c39f11 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -353,7 +353,8 @@
@override
void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {
- if (typeEnvironment.isSubtypeOf(operandType, node.type)) {
+ if (typeEnvironment.isSubtypeOf(
+ operandType, node.type, ir.SubtypeCheckMode.ignoringNullabilities)) {
// Skip unneeded casts.
return;
}
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 084ffd0..d686190 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -286,7 +286,8 @@
getTypeAsInstanceOf(receiverType, superclass));
ir.DartType setterType =
receiverSubstitution.substituteType(interfaceTarget.setterType);
- if (!typeEnvironment.isSubtypeOf(valueType, setterType)) {
+ if (!typeEnvironment.isSubtypeOf(
+ valueType, setterType, ir.SubtypeCheckMode.ignoringNullabilities)) {
// We need to insert an implicit cast to preserve the invariant that
// a property set with a known interface target is also statically
// checked.
@@ -484,7 +485,8 @@
for (int i = 0; i < node.arguments.positional.length; i++) {
ir.DartType argumentType = argumentTypes.positional[i];
ir.DartType parameterType = parameterTypes.positionalParameters[i];
- if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+ if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+ ir.SubtypeCheckMode.ignoringNullabilities)) {
neededPositionalChecks[i] = parameterType;
}
}
@@ -497,7 +499,8 @@
ir.DartType parameterType = parameterTypes.namedParameters
.singleWhere((namedType) => namedType.name == namedArgument.name)
.type;
- if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+ if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+ ir.SubtypeCheckMode.ignoringNullabilities)) {
neededNamedChecks[argumentIndex] = parameterType;
}
}
@@ -719,7 +722,8 @@
assert(
node.promotedType == null ||
promotedType == typeEnvironment.nullType ||
- typeEnvironment.isSubtypeOf(promotedType, node.promotedType),
+ typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
+ ir.SubtypeCheckMode.ignoringNullabilities),
"Unexpected promotion of ${node.variable} in ${node.parent}. "
"Expected ${node.promotedType}, found $promotedType");
_expressionTypeCache[node] = promotedType;
@@ -1474,7 +1478,8 @@
// TODO(johnniwinther): Special-case the `== null` representation to
// make it faster.
for (ir.DartType type in falseTypes) {
- if (typeEnvironment.isSubtypeOf(declaredType, type)) {
+ if (typeEnvironment.isSubtypeOf(
+ declaredType, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
return typeEnvironment.nullType;
}
}
@@ -1484,9 +1489,11 @@
if (type == typeEnvironment.nullType) {
return type;
}
- if (typeEnvironment.isSubtypeOf(type, candidate)) {
+ if (typeEnvironment.isSubtypeOf(
+ type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
candidate = type;
- } else if (!typeEnvironment.isSubtypeOf(candidate, type)) {
+ } else if (!typeEnvironment.isSubtypeOf(
+ candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
// We cannot promote. No single type is most specific.
// TODO(johnniwinther): Compute implied types? For instance when the
// declared type is `Iterable<String>` and tested type is
@@ -1745,9 +1752,11 @@
// Keep the current candidate.
} else if (candidate == typeEnvironment.nullType) {
candidate = type;
- } else if (typeEnvironment.isSubtypeOf(candidate, type)) {
+ } else if (typeEnvironment.isSubtypeOf(
+ candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
candidate = type;
- } else if (!typeEnvironment.isSubtypeOf(type, candidate)) {
+ } else if (!typeEnvironment.isSubtypeOf(
+ type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
// We cannot promote. No promoted type of one path is a supertype of
// the promoted type from all other paths.
// TODO(johnniwinther): Compute a greatest lower bound, instead?
@@ -1872,7 +1881,8 @@
changed = true;
Set<ir.DartType> newTypesOfInterest = new Set<ir.DartType>();
for (ir.DartType typeOfInterest in info.typesOfInterest) {
- if (typeEnvironment.isSubtypeOf(type, typeOfInterest)) {
+ if (typeEnvironment.isSubtypeOf(type, typeOfInterest,
+ ir.SubtypeCheckMode.ignoringNullabilities)) {
newTypesOfInterest.add(typeOfInterest);
}
}
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index 6c08757..b41805a 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -728,7 +728,8 @@
}
DartType type = elementMap.commonElements
.listType(elementMap.getDartType(node.typeArgument));
- return constant_system.createList(type, elements);
+ return constant_system.createList(
+ elementMap.commonElements, type, elements);
}
@override
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index b9a78c9..b7dfa1a 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -473,10 +473,7 @@
jsAst.Expression maybeAddListTypeArgumentsNewRti(
ConstantValue constant, InterfaceType type, jsAst.Expression value) {
- // List<T> --> JSArray<T>
- if (type.element != _commonElements.jsArrayClass) {
- type = InterfaceType(_commonElements.jsArrayClass, type.typeArguments);
- }
+ assert(type.element == _commonElements.jsArrayClass);
if (_rtiNeed.classNeedsTypeArguments(type.element)) {
return new jsAst.Call(
getHelperProperty(_commonElements.setRuntimeTypeInfo),
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index b6f90d4..13fbaf9 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -35,57 +35,6 @@
InterceptorData get _interceptorData => _closedWorld.interceptorData;
- jsAst.Expression generateClassConstructor(
- ClassEntity classElement, List<jsAst.Name> fields, bool hasRtiField) {
- // TODO(sra): Implement placeholders in VariableDeclaration position:
- //
- // String constructorName = namer.getNameOfClass(classElement);
- // return js.statement('function #(#) { #; }',
- // [ constructorName, fields,
- // fields.map(
- // (name) => js('this.# = #', [name, name]))]));
- dynamic typeParameters = const <jsAst.Parameter>[];
- dynamic typeInits = const <jsAst.Expression>[];
- if (hasRtiField) {
- dynamic rtiName = _namer.rtiFieldJsName;
- typeParameters = rtiName;
- typeInits = js('this.# = #', [rtiName, rtiName]);
- }
- List<jsAst.Parameter> parameters = new List<jsAst.Parameter>.generate(
- fields.length, (i) => new jsAst.Parameter('t$i'));
- List<jsAst.Expression> fieldInitializers =
- new List<jsAst.Expression>.generate(fields.length, (i) {
- return js('this.# = #', [fields[i], parameters[i]]);
- });
- return js('function(#, #) { #; #; this.#();}', [
- parameters,
- typeParameters,
- fieldInitializers,
- typeInits,
- _namer.fixedNames.deferredAction
- ]);
- }
-
- jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) {
- ClassEntity cls = member.enclosingClass;
- String receiver =
- _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
- List<String> args =
- _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
- return js('function(#) { return #.# }', [args, receiver, fieldName]);
- }
-
- jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) {
- ClassEntity cls = member.enclosingClass;
- String receiver =
- _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
- List<String> args =
- _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
- // TODO(floitsch): remove 'return'?
- return js(
- 'function(#, v) { return #.# = v; }', [args, receiver, fieldName]);
- }
-
/// Documentation wanted -- johnniwinther
///
/// Invariant: [member] must be a declaration element.
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 78da253..4e4571e 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -847,7 +847,8 @@
if (member.isAbstract) {
cls = elementMap.elementEnvironment.getSuperClass(cls);
} else {
- return member.enclosingClass != commonElements.objectClass;
+ return member.enclosingClass != commonElements.objectClass &&
+ member.enclosingClass != commonElements.jsInterceptorClass;
}
}
return false;
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index f15d5d2..475c993 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -140,12 +140,13 @@
}[parsedArgs['output-kind']];
final sourcePath = path.canonicalize(path.normalize(parsedArgs.rest[0]));
+ final sourceWithoutDart = sourcePath.replaceFirst(new RegExp(r'\.dart$'), '');
final outputPath =
path.canonicalize(path.normalize(parsedArgs['output'] != null
? parsedArgs['output']
: {
- Kind.aot: '${sourcePath}.aot',
- Kind.exe: '${sourcePath}.exe',
+ Kind.aot: '${sourceWithoutDart}.aot',
+ Kind.exe: '${sourceWithoutDart}.exe',
}[kind]));
if (!FileSystemEntity.isFileSync(sourcePath)) {
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 645dd90..4a2f6e6 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -446,10 +446,14 @@
/// Returns the canonical name to refer to the Dart library.
@protected
js_ast.Identifier emitLibraryName(Library library) {
+ // Avoid adding the dart:_runtime to _imports when our runtime unit tests
+ // import it explicitly. It will always be implicitly imported.
+ if (isSdkInternalRuntime(library)) return runtimeModule;
+
// It's either one of the libraries in this module, or it's an import.
- var libraryId = js_ast.TemporaryId(jsLibraryName(library));
return _libraries[library] ??
- _imports.putIfAbsent(library, () => libraryId);
+ _imports.putIfAbsent(
+ library, () => js_ast.TemporaryId(jsLibraryName(library)));
}
/// Emits imports and extension methods into [items].
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index c741457..8401522 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -243,6 +243,7 @@
fe.IncrementalCompiler incrementalCompiler;
fe.WorkerInputComponent cachedSdkInput;
bool recordUsedInputs = argResults['used-inputs-file'] != null;
+ List<Uri> inputSummaries = summaryModules.keys.toList();
if (useAnalyzer || !useIncrementalCompiler) {
compilerState = await fe.initializeCompiler(
oldCompilerState,
@@ -251,7 +252,7 @@
compileSdk ? null : sourcePathToUri(sdkSummaryPath),
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
- summaryModules.keys.toList(),
+ inputSummaries,
DevCompilerTarget(
TargetFlags(trackWidgetCreation: trackWidgetCreation)),
fileSystem: fileSystem,
@@ -286,7 +287,7 @@
compileSdk ? null : sourcePathToUri(sdkSummaryPath),
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
- summaryModules.keys.toList(),
+ inputSummaries,
inputDigests,
DevCompilerTarget(
TargetFlags(trackWidgetCreation: trackWidgetCreation)),
@@ -299,8 +300,6 @@
compilerState.workerInputCache[sourcePathToUri(sdkSummaryPath)];
}
- List<Uri> inputSummaries = compilerState.options.inputSummaries;
-
// TODO(jmesserly): is there a cleaner way to do this?
//
// Ideally we'd manage our own batch compilation caching rather than rely on
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 57b2fe0..db30dd1 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5044,7 +5044,10 @@
// }
//
var isTypeError = node.isTypeError;
- if (!isTypeError && _types.isSubtypeOf(from, to)) return jsFrom;
+ if (!isTypeError &&
+ _types.isSubtypeOf(from, to, SubtypeCheckMode.ignoringNullabilities)) {
+ return jsFrom;
+ }
// All Dart number types map to a JS double.
if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 5ae85a5..3bd4a1f 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -64,7 +64,16 @@
uri.scheme == 'dart' &&
(uri.path == 'core' || uri.path == '_interceptors');
+ /// Returns [true] if [uri] represents a test script has been whitelisted to
+ /// import private platform libraries.
+ ///
+ /// Unit tests for the dart:_runtime library have imports like this. It is
+ /// only allowed from a specific SDK test directory or through the modular
+ /// test framework.
bool _allowedTestLibrary(Uri uri) {
+ // Multi-root scheme used by modular test framework.
+ if (uri.scheme == 'dev-dart-app') return true;
+
String scriptName = uri.path;
return scriptName.contains('tests/compiler/dartdevc_native');
}
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
index fac2975..4c2a413 100644
--- a/pkg/dev_compiler/test/modular_ddc_suite.dart
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -36,7 +36,17 @@
IOPipeline([
DDCStep(),
RunD8(),
- ], cacheSharedModules: true, saveIntermediateResultsForTesting: false));
+ ], cacheSharedModules: true));
+
+ // DDC only test suite.
+ await runSuite(
+ sdkRoot.resolve('tests/compiler/dartdevc/modular/'),
+ 'tests/compiler/dartdevc/modular',
+ _options,
+ IOPipeline([
+ DDCStep(),
+ RunD8(),
+ ], cacheSharedModules: true));
}
const sumId = DataId("sum");
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 2442d93..0b4e1e6 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -81,6 +81,9 @@
extraArgs = ['--packages-file', '$rootScheme:/.packages'];
}
+ Module sdkModule =
+ module.isSdk ? module : module.dependencies.firstWhere((m) => m.isSdk);
+
List<String> args = [
_kernelWorkerScript,
'--summary-only',
@@ -93,8 +96,14 @@
...extraArgs,
'--output',
'${toUri(module, dillId)}',
+ if (!module.isSdk) ...[
+ '--dart-sdk-summary',
+ '${toUri(sdkModule, dillId)}',
+ '--exclude-non-sources',
+ ],
...(transitiveDependencies
- .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+ .where((m) => !m.isSdk)
+ .expand((m) => ['--input-summary', '${toUri(m, dillId)}'])),
...(sources.expand((String uri) => ['--source', uri])),
...(flags.expand((String flag) => ['--enable-experiment', flag])),
];
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 052e2dd..d36bd4a 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -43,7 +43,7 @@
const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
ExperimentalFlag.constantUpdate2018: true,
ExperimentalFlag.controlFlowCollections: true,
- ExperimentalFlag.extensionMethods: false,
+ ExperimentalFlag.extensionMethods: true,
ExperimentalFlag.nonNullable: false,
ExperimentalFlag.setLiterals: true,
ExperimentalFlag.spreadCollections: true,
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index fd091bb..3618c93 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -26,7 +26,9 @@
Uri currentDirectory;
MemoryFileSystem(Uri currentDirectory)
- : currentDirectory = _addTrailingSlash(currentDirectory);
+ : currentDirectory = _addTrailingSlash(currentDirectory) {
+ _directories.add(currentDirectory);
+ }
@override
MemoryFileSystemEntity entityForUri(Uri uri) {
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 6c6b5a4..57080d9 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -9,7 +9,7 @@
import 'package:front_end/src/api_prototype/compiler_options.dart';
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component, Library;
import 'package:kernel/target/targets.dart' show Target;
@@ -20,23 +20,27 @@
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
-import '../api_prototype/front_end.dart' show CompilerResult;
-
import '../api_prototype/file_system.dart' show FileSystem;
+import '../api_prototype/front_end.dart' show CompilerResult;
+
import '../base/processed_options.dart' show ProcessedOptions;
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
import '../kernel_generator_impl.dart' show generateKernel;
-import 'compiler_state.dart'
- show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
+
+import 'modular_incremental_compilation.dart' as modular
+ show initializeIncrementalCompiler;
+
+export '../api_prototype/compiler_options.dart'
+ show parseExperimentalFlags, parseExperimentalArguments;
export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
+export '../api_prototype/experimental_flags.dart'
+ show ExperimentalFlag, parseExperimentalFlag;
+
export '../api_prototype/standard_file_system.dart' show StandardFileSystem;
export '../api_prototype/terminal_color_support.dart'
@@ -48,11 +52,9 @@
export 'compiler_state.dart' show InitializedCompilerState;
-import 'util.dart' show equalMaps, equalSets;
-
/// Initializes the compiler for a modular build.
///
-/// Re-uses cached components from [_workerInputCache], and reloads them
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
/// as necessary based on [workerInputDigests].
Future<InitializedCompilerState> initializeIncrementalCompiler(
InitializedCompilerState oldState,
@@ -67,193 +69,26 @@
Iterable<String> experiments,
bool outlineOnly,
{bool trackNeededDillLibraries: false}) async {
- final List<int> sdkDigest = workerInputDigests[sdkSummary];
- if (sdkDigest == null) {
- throw new StateError("Expected to get digest for $sdkSummary");
- }
- IncrementalCompiler incrementalCompiler;
- CompilerOptions options;
- ProcessedOptions processedOpts;
- 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;
+ List<Component> outputLoadedInputSummaries =
+ new List<Component>(summaryInputs.length);
Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
parseExperimentalArguments(experiments),
onError: (e) => throw e);
-
- if (oldState == null ||
- oldState.incrementalCompiler == null ||
- oldState.incrementalCompiler.outlineOnly != outlineOnly ||
- !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
- !equalSets(oldState.tags, tags)) {
- // No - or immediately not correct - previous state.
- startOver = true;
-
- // 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];
- if (cachedSdkInput == null ||
- !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
- // The sdk is out of date.
- startOver = true;
- // We'll load a new sdk, anything loaded already will have a wrong root.
- workerInputCache.clear();
- workerInputCacheLibs.clear();
- }
- }
-
- if (startOver) {
- // The sdk was either not cached or it has changed.
- options = new CompilerOptions()
- ..sdkSummary = sdkSummary
- ..packagesFileUri = packagesFile
- ..librariesSpecificationUri = librariesSpecificationUri
- ..target = target
- ..fileSystem = fileSystem
- ..omitPlatform = true
- ..environmentDefines = const {}
- ..experimentalFlags = experimentalFlags;
-
- 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,
- outlineOnly);
- incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
- } else {
- options = oldState.options;
- processedOpts = oldState.processedOpts;
- Component sdkComponent = cachedSdkInput.component;
- // Reset the state of the component.
- for (Library lib in sdkComponent.libraries) {
- lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
- }
-
- // Make sure the canonical name root knows about the sdk - otherwise we
- // won't be able to link to it when loading more outlines.
- sdkComponent.adoptChildren();
-
- // TODO(jensj): This is - at least currently - necessary,
- // although it's not entirely obvious why.
- // It likely has to do with several outlines containing the same libraries.
- // Once that stops (and we check for it) we can probably remove this,
- // and instead only do it when about to reuse an outline in the
- // 'inputSummaries.add(component);' line further down.
- for (WorkerInputComponent cachedInput in workerInputCache.values) {
- cachedInput.component.adoptChildren();
- }
-
- // Reuse the incremental compiler, but reset as needed.
- incrementalCompiler = oldState.incrementalCompiler;
- incrementalCompiler.invalidateAllSources();
- incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
- options.packagesFileUri = packagesFile;
- options.fileSystem = fileSystem;
- processedOpts.clearFileSystemCache();
- }
-
- // Then read all the input summary components.
- CanonicalName nameRoot = cachedSdkInput.component.root;
- final List<Component> inputSummaries = <Component>[];
- Map<Uri, Uri> libraryToInputDill;
- if (trackNeededDillLibraries) {
- 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) {
- throw new StateError("Expected to get digest for $summary");
- }
- 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.
- Component component = cachedInput.component;
- for (Library lib in component.libraries) {
- lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
- if (trackNeededDillLibraries) {
- libraryToInputDill[lib.importUri] = summary;
- }
- }
- inputSummaries.add(component);
- }
- }
-
- for (int i = 0; i < loadFromDill.length; i++) {
- Uri summary = loadFromDill[i];
- List<int> summaryDigest = workerInputDigests[summary];
- if (summaryDigest == null) {
- throw new StateError("Expected to get digest for $summary");
- }
- WorkerInputComponent cachedInput = new WorkerInputComponent(
- summaryDigest,
- await processedOpts.loadComponent(
- await fileSystem.entityForUri(summary).readAsBytes(), nameRoot,
- alwaysCreateNewNamedNodes: true));
- workerInputCache[summary] = cachedInput;
- inputSummaries.add(cachedInput.component);
- 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;
- }
- }
- }
-
- incrementalCompiler.setModulesToLoadOnNextComputeDelta(inputSummaries);
-
- return new InitializedCompilerState(options, processedOpts,
- workerInputCache: workerInputCache,
- workerInputCacheLibs: workerInputCacheLibs,
- incrementalCompiler: incrementalCompiler,
- tags: tags,
- libraryToInputDill: libraryToInputDill);
+ return modular.initializeIncrementalCompiler(
+ oldState,
+ tags,
+ outputLoadedInputSummaries,
+ sdkSummary,
+ packagesFile,
+ librariesSpecificationUri,
+ summaryInputs,
+ workerInputDigests,
+ target,
+ fileSystem: fileSystem,
+ experimentalFlags: experimentalFlags,
+ outlineOnly: outlineOnly,
+ omitPlatform: true,
+ trackNeededDillLibraries: trackNeededDillLibraries);
}
Future<InitializedCompilerState> initializeCompiler(
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 8885e67..0a5122b 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -6,7 +6,7 @@
import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component;
import 'package:kernel/target/targets.dart' show Target;
@@ -24,16 +24,14 @@
import '../base/processed_options.dart' show ProcessedOptions;
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
import '../kernel_generator_impl.dart' show generateKernel;
-import 'compiler_state.dart'
- show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
-import 'util.dart' show equalLists, equalMaps, equalSets;
+import 'modular_incremental_compilation.dart' as modular
+ show initializeIncrementalCompiler;
+
+import 'util.dart' show equalLists, equalMaps;
export '../api_prototype/compiler_options.dart'
show CompilerOptions, parseExperimentalFlags, parseExperimentalArguments;
@@ -132,6 +130,10 @@
return new InitializedCompilerState(options, processedOpts);
}
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
Future<InitializedCompilerState> initializeIncrementalCompiler(
InitializedCompilerState oldState,
Set<String> tags,
@@ -148,183 +150,25 @@
Map<ExperimentalFlag, bool> experiments,
Map<String, String> environmentDefines,
bool trackNeededDillLibraries: false}) async {
- inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
-
- IncrementalCompiler incrementalCompiler;
- WorkerInputComponent cachedSdkInput;
- CompilerOptions options;
- ProcessedOptions processedOpts;
-
- 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");
- }
-
- cachedSdkInput = workerInputCache[sdkSummary];
-
- if (oldState == null ||
- oldState.incrementalCompiler == null ||
- oldState.options.compileSdk != compileSdk ||
- cachedSdkInput == null ||
- !digestsEqual(cachedSdkInput.digest, sdkDigest) ||
- !equalMaps(oldState.options.experimentalFlags, experiments) ||
- !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
- !equalSets(oldState.tags, tags)) {
- // No - or immediately not correct - previous state.
- options = new CompilerOptions()
- ..compileSdk = compileSdk
- ..sdkRoot = sdkRoot
- ..sdkSummary = sdkSummary
- ..packagesFileUri = packagesFile
- ..inputSummaries = inputSummaries
- ..librariesSpecificationUri = librariesSpecificationUri
- ..target = target
- ..fileSystem = fileSystem ?? StandardFileSystem.instance
- ..environmentDefines = environmentDefines;
- if (experiments != null) options.experimentalFlags = experiments;
-
- // 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;
- } else {
- options = oldState.options;
- options.inputSummaries = inputSummaries;
- processedOpts = oldState.processedOpts;
-
- for (Library lib in cachedSdkInput.component.libraries) {
- lib.isExternal = false;
- }
- cachedSdkInput.component.adoptChildren();
- for (WorkerInputComponent cachedInput in workerInputCache.values) {
- cachedInput.component.adoptChildren();
- }
-
- // Reuse the incremental compiler, but reset as needed.
- incrementalCompiler = oldState.incrementalCompiler;
- incrementalCompiler.invalidateAllSources();
- incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
- options.packagesFileUri = packagesFile;
- options.fileSystem = fileSystem;
- processedOpts.clearFileSystemCache();
- }
- InitializedCompilerState compilerState = new InitializedCompilerState(
- options, processedOpts,
- workerInputCache: workerInputCache,
- incrementalCompiler: incrementalCompiler);
-
- CanonicalName nameRoot = cachedSdkInput.component.root;
- Map<Uri, Uri> libraryToInputDill;
- if (trackNeededDillLibraries) {
- libraryToInputDill = new Map<Uri, Uri>();
- }
- List<int> loadFromDillIndexes = new List<int>();
-
- // Notice that the ordering of the input summaries matter, so we need to
- // keep them in order.
- 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) {
- throw new StateError("Expected to get digest for $inputSummary");
- }
- 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.
- Component component = cachedInput.component;
- for (Library lib in component.libraries) {
- lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
- if (trackNeededDillLibraries) {
- libraryToInputDill[lib.importUri] = inputSummary;
- }
- }
- component.computeCanonicalNames();
- doneInputSummaries[i] = component;
- }
- }
-
- for (int i = 0; i < loadFromDillIndexes.length; i++) {
- int index = loadFromDillIndexes[i];
- Uri summary = inputSummaries[index];
- List<int> digest = workerInputDigests[summary];
- if (digest == null) {
- throw new StateError("Expected to get digest for $summary");
- }
- List<int> bytes = await fileSystem.entityForUri(summary).readAsBytes();
- WorkerInputComponent cachedInput = new WorkerInputComponent(
- digest,
- await compilerState.processedOpts
- .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
- workerInputCache[summary] = cachedInput;
- doneInputSummaries[index] = cachedInput.component;
- 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;
- }
- }
- }
-
- incrementalCompiler.setModulesToLoadOnNextComputeDelta(doneInputSummaries);
-
- return new InitializedCompilerState(options, processedOpts,
- workerInputCache: workerInputCache,
- workerInputCacheLibs: workerInputCacheLibs,
- incrementalCompiler: incrementalCompiler,
- tags: tags,
- libraryToInputDill: libraryToInputDill);
+ return modular.initializeIncrementalCompiler(
+ oldState,
+ tags,
+ doneInputSummaries,
+ sdkSummary,
+ packagesFile,
+ librariesSpecificationUri,
+ inputSummaries,
+ workerInputDigests,
+ target,
+ compileSdk: compileSdk,
+ sdkRoot: sdkRoot,
+ fileSystem: fileSystem ?? StandardFileSystem.instance,
+ experimentalFlags: experiments,
+ environmentDefines:
+ environmentDefines ?? const <ExperimentalFlag, bool>{},
+ outlineOnly: false,
+ omitPlatform: false,
+ trackNeededDillLibraries: trackNeededDillLibraries);
}
Future<DdcResult> compile(InitializedCompilerState compilerState,
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
new file mode 100644
index 0000000..5244f74
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.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.
+
+import 'dart:async' show Future;
+
+import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+
+import 'package:kernel/target/targets.dart' show Target;
+
+import '../api_prototype/compiler_options.dart' show CompilerOptions;
+
+import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
+
+import '../api_prototype/file_system.dart' show FileSystem;
+
+import '../base/processed_options.dart' show ProcessedOptions;
+
+import '../fasta/compiler_context.dart' show CompilerContext;
+
+import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
+
+import 'compiler_state.dart'
+ show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+
+import 'util.dart' show equalMaps, equalSets;
+
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
+///
+/// Notes:
+/// * [outputLoadedInputSummaries] should be given as an empty list of the same
+/// size as the [inputSummaries]. The input summaries are loaded (or taken
+/// from cache) and placed in this list in order, i.e. the `i`-th entry in
+/// [outputLoadedInputSummaries] after this call corresponds to the component
+/// loaded from the `i`-th entry in [inputSummaries].
+Future<InitializedCompilerState> initializeIncrementalCompiler(
+ InitializedCompilerState oldState,
+ Set<String> tags,
+ List<Component> outputLoadedInputSummaries,
+ Uri sdkSummary,
+ Uri packagesFile,
+ Uri librariesSpecificationUri,
+ List<Uri> inputSummaries,
+ Map<Uri, List<int>> workerInputDigests,
+ Target target,
+ {bool compileSdk: false,
+ Uri sdkRoot: null,
+ FileSystem fileSystem,
+ Map<ExperimentalFlag, bool> experimentalFlags,
+ Map<String, String> environmentDefines: const {},
+ bool outlineOnly,
+ bool omitPlatform: false,
+ bool trackNeededDillLibraries: false}) async {
+ final List<int> sdkDigest = workerInputDigests[sdkSummary];
+ if (sdkDigest == null) {
+ throw new StateError("Expected to get digest for $sdkSummary");
+ }
+
+ Map<Uri, WorkerInputComponent> workerInputCache =
+ oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+ Map<Uri, Uri> workerInputCacheLibs =
+ oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
+
+ WorkerInputComponent cachedSdkInput = workerInputCache[sdkSummary];
+
+ IncrementalCompiler incrementalCompiler;
+ CompilerOptions options;
+ ProcessedOptions processedOpts;
+
+ if (oldState == null ||
+ oldState.incrementalCompiler == null ||
+ oldState.options.compileSdk != compileSdk ||
+ oldState.incrementalCompiler.outlineOnly != outlineOnly ||
+ !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
+ !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
+ !equalSets(oldState.tags, tags) ||
+ cachedSdkInput == null ||
+ !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
+ // No - or immediately not correct - previous state.
+ // We'll load a new sdk, anything loaded already will have a wrong root.
+ workerInputCache.clear();
+ workerInputCacheLibs.clear();
+
+ // The sdk was either not cached or it has changed.
+ options = new CompilerOptions()
+ ..compileSdk = compileSdk
+ ..sdkRoot = sdkRoot
+ ..sdkSummary = sdkSummary
+ ..packagesFileUri = packagesFile
+ ..librariesSpecificationUri = librariesSpecificationUri
+ ..target = target
+ ..fileSystem = fileSystem
+ ..omitPlatform = omitPlatform
+ ..environmentDefines = environmentDefines
+ ..experimentalFlags = experimentalFlags;
+
+ 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,
+ outlineOnly);
+ incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+ } else {
+ options = oldState.options;
+ processedOpts = oldState.processedOpts;
+ Component sdkComponent = cachedSdkInput.component;
+ // Reset the state of the component.
+ for (Library lib in sdkComponent.libraries) {
+ lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
+ }
+
+ // Make sure the canonical name root knows about the sdk - otherwise we
+ // won't be able to link to it when loading more outlines.
+ sdkComponent.adoptChildren();
+
+ // TODO(jensj): This is - at least currently - necessary,
+ // although it's not entirely obvious why.
+ // It likely has to do with several outlines containing the same libraries.
+ // Once that stops (and we check for it) we can probably remove this,
+ // and instead only do it when about to reuse an outline in the
+ // 'inputSummaries.add(component);' line further down.
+ for (WorkerInputComponent cachedInput in workerInputCache.values) {
+ cachedInput.component.adoptChildren();
+ }
+
+ // Reuse the incremental compiler, but reset as needed.
+ incrementalCompiler = oldState.incrementalCompiler;
+ incrementalCompiler.invalidateAllSources();
+ incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+ options.packagesFileUri = packagesFile;
+ options.fileSystem = fileSystem;
+ processedOpts.clearFileSystemCache();
+ }
+
+ // Then read all the input summary components.
+ CanonicalName nameRoot = cachedSdkInput.component.root;
+ Map<Uri, Uri> libraryToInputDill;
+ if (trackNeededDillLibraries) {
+ libraryToInputDill = new Map<Uri, Uri>();
+ }
+ List<int> loadFromDillIndexes = new List<int>();
+
+ // Notice that the ordering of the input summaries matter, so we need to
+ // keep them in order.
+ if (outputLoadedInputSummaries.length != inputSummaries.length) {
+ throw new ArgumentError("Invalid length.");
+ }
+ Set<Uri> inputSummariesSet = new Set<Uri>();
+ for (int i = 0; i < inputSummaries.length; i++) {
+ Uri summaryUri = inputSummaries[i];
+ inputSummariesSet.add(summaryUri);
+ WorkerInputComponent cachedInput = workerInputCache[summaryUri];
+ List<int> digest = workerInputDigests[summaryUri];
+ if (digest == null) {
+ throw new StateError("Expected to get digest for $summaryUri");
+ }
+ 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.
+ Component component = cachedInput.component;
+ for (Library lib in component.libraries) {
+ lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
+ if (trackNeededDillLibraries) {
+ libraryToInputDill[lib.importUri] = summaryUri;
+ }
+ }
+ component.computeCanonicalNames(); // this isn't needed, is it?
+ outputLoadedInputSummaries[i] = component;
+ }
+ }
+
+ for (int i = 0; i < loadFromDillIndexes.length; i++) {
+ int index = loadFromDillIndexes[i];
+ Uri summaryUri = inputSummaries[index];
+ List<int> digest = workerInputDigests[summaryUri];
+ if (digest == null) {
+ throw new StateError("Expected to get digest for $summaryUri");
+ }
+
+ List<int> bytes = await fileSystem.entityForUri(summaryUri).readAsBytes();
+ WorkerInputComponent cachedInput = new WorkerInputComponent(
+ digest,
+ await processedOpts.loadComponent(bytes, nameRoot,
+ alwaysCreateNewNamedNodes: true));
+ workerInputCache[summaryUri] = cachedInput;
+ outputLoadedInputSummaries[index] = cachedInput.component;
+ 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] = summaryUri;
+ }
+
+ if (trackNeededDillLibraries) {
+ libraryToInputDill[lib.importUri] = summaryUri;
+ }
+ }
+ }
+
+ incrementalCompiler
+ .setModulesToLoadOnNextComputeDelta(outputLoadedInputSummaries);
+
+ return new InitializedCompilerState(options, processedOpts,
+ workerInputCache: workerInputCache,
+ workerInputCacheLibs: workerInputCacheLibs,
+ incrementalCompiler: incrementalCompiler,
+ tags: tags,
+ libraryToInputDill: libraryToInputDill);
+}
diff --git a/pkg/front_end/lib/src/base/common.dart b/pkg/front_end/lib/src/base/common.dart
new file mode 100644
index 0000000..e511a04
--- /dev/null
+++ b/pkg/front_end/lib/src/base/common.dart
@@ -0,0 +1,6 @@
+// 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.
+
+/// If `true`, data that would not otherwise be kept is stored for testing.
+bool retainDataForTesting = false;
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 c4a1632..ee0b627 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -51,7 +51,10 @@
import 'package:kernel/type_algebra.dart' as type_algebra
show getSubstitutionMap;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+ show SubtypeCheckMode, TypeEnvironment;
+
+import '../../base/common.dart';
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
@@ -166,6 +169,8 @@
ClassBuilder actualOrigin;
+ ClassBuilder patchForTesting;
+
ClassBuilder(
List<MetadataBuilder> metadata,
int modifiers,
@@ -1165,9 +1170,12 @@
DartType subtype = inParameter ? interfaceType : declaredType;
DartType supertype = inParameter ? declaredType : interfaceType;
- if (types.isSubtypeOfKernel(subtype, supertype)) {
+ if (types.isSubtypeOfKernel(
+ subtype, supertype, SubtypeCheckMode.ignoringNullabilities)) {
// No problem--the proper subtyping relation is satisfied.
- } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
+ } else if (isCovariant &&
+ types.isSubtypeOfKernel(
+ supertype, subtype, SubtypeCheckMode.ignoringNullabilities)) {
// No problem--the overriding parameter is marked "covariant" and has
// a type which is a subtype of the parameter it overrides.
} else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1523,6 +1531,9 @@
void applyPatch(Builder patch) {
if (patch is ClassBuilder) {
patch.actualOrigin = this;
+ if (retainDataForTesting) {
+ patchForTesting = patch;
+ }
// TODO(ahe): Complain if `patch.supertype` isn't null.
scope.local.forEach((String name, Builder member) {
Builder memberPatch = patch.scope.local[name];
@@ -1627,7 +1638,8 @@
DartType typeArgument = typeArguments[i];
// Check whether the [typeArgument] respects the bounds of
// [typeParameter].
- if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound)) {
+ if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
+ SubtypeCheckMode.ignoringNullabilities)) {
addProblem(
templateRedirectingFactoryIncompatibleTypeArgument.withArguments(
typeArgument, typeParameterBound),
@@ -1685,7 +1697,8 @@
if (redirecteeType == null) return;
// Check whether [redirecteeType] <: [factoryType].
- if (!typeEnvironment.isSubtypeOf(redirecteeType, factoryType)) {
+ if (!typeEnvironment.isSubtypeOf(
+ redirecteeType, factoryType, SubtypeCheckMode.ignoringNullabilities)) {
addProblem(
templateIncompatibleRedirecteeFunctionType.withArguments(
redirecteeType, factoryType),
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index f591207..2f1777b 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -156,4 +156,10 @@
newTypes.add(newType);
return newType;
}
+
+ FunctionTypeBuilder withNullabilityBuilder(
+ NullabilityBuilder nullabilityBuilder) {
+ return new FunctionTypeBuilder(
+ returnType, typeVariables, formals, nullabilityBuilder);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
index a0f7861..2ecb4a6 100644
--- a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
@@ -4,7 +4,8 @@
library fasta.mixin_application_builder;
-import 'builder.dart' show LibraryBuilder, TypeBuilder, TypeVariableBuilder;
+import 'builder.dart'
+ show LibraryBuilder, NullabilityBuilder, TypeBuilder, TypeVariableBuilder;
import 'package:kernel/ast.dart' show InterfaceType, Supertype;
@@ -23,6 +24,10 @@
String get name => null;
+ NullabilityBuilder get nullabilityBuilder {
+ return unsupported("nullabilityBuilder", -1, null);
+ }
+
String get debugName => "MixinApplicationBuilder";
StringBuffer printOn(StringBuffer buffer) {
@@ -61,6 +66,12 @@
return unsupported("buildInvalidType", message.charOffset, message.uri);
}
+ @override
+ MixinApplicationBuilder withNullabilityBuilder(
+ NullabilityBuilder nullabilityBuilder) {
+ return unsupported("withNullabilityBuilder", -1, null);
+ }
+
MixinApplicationBuilder clone(List<TypeBuilder> newTypes) {
int charOffset = -1; // TODO(dmitryas): Provide these.
Uri fileUri = null; // TODO(dmitryas): Provide these.
diff --git a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
index 6357975..592ecf2 100644
--- a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
@@ -74,5 +74,6 @@
return buffer..write(name ?? fullNameForErrors);
}
- String toString() => "$debugName(${printOn(new StringBuffer())})";
+ String toString() =>
+ "${isPatch ? 'patch ' : ''}$debugName(${printOn(new StringBuffer())})";
}
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 38a57ae..a956d76 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
@@ -296,4 +296,10 @@
newTypes.add(newType);
return newType;
}
+
+ NamedTypeBuilder withNullabilityBuilder(
+ NullabilityBuilder nullabilityBuilder) {
+ return new NamedTypeBuilder(name, nullabilityBuilder, arguments)
+ ..bind(declaration);
+ }
}
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 d818e4d..0335f23 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -11,6 +11,8 @@
import 'package:kernel/type_algebra.dart';
+import '../../base/common.dart';
+
import 'builder.dart'
show
Builder,
@@ -459,6 +461,7 @@
final Procedure _procedure;
final int charOpenParenOffset;
final ProcedureKind kind;
+ ProcedureBuilder patchForTesting;
AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
@@ -553,8 +556,8 @@
_procedure.isConst = isConst;
if (isExtensionMethod) {
ExtensionBuilder extensionBuilder = parent;
- procedure.isExtensionMember = true;
- procedure.isStatic = true;
+ _procedure.isExtensionMember = true;
+ _procedure.isStatic = true;
String kindInfix = '';
if (isExtensionInstanceMember) {
// Instance getter and setter are converted to methods so we use an
@@ -574,18 +577,18 @@
throw new UnsupportedError(
'Unexpected extension method kind ${kind}');
}
- procedure.kind = ProcedureKind.Method;
+ _procedure.kind = ProcedureKind.Method;
}
- procedure.name = new Name(
+ _procedure.name = new Name(
'${extensionBuilder.name}|${kindInfix}${name}',
libraryBuilder.library);
} else {
_procedure.isStatic = isStatic;
_procedure.name = new Name(name, libraryBuilder.library);
}
- }
- if (extensionTearOff != null) {
- _buildExtensionTearOff(libraryBuilder, parent);
+ if (extensionTearOff != null) {
+ _buildExtensionTearOff(libraryBuilder, parent);
+ }
}
return _procedure;
}
@@ -698,7 +701,7 @@
Statement closureBody = new ReturnStatement(
new StaticInvocation(
- procedure,
+ _procedure,
new Arguments(closurePositionalArguments,
types: typeArguments, named: closureNamedArguments))
..fileOffset = fileOffset)
@@ -709,10 +712,10 @@
typeParameters: closureTypeParameters,
positionalParameters: closurePositionalParameters,
namedParameters: closureNamedParameters,
- requiredParameterCount: procedure.function.requiredParameterCount - 1,
+ requiredParameterCount: _procedure.function.requiredParameterCount - 1,
returnType: closureReturnType,
- asyncMarker: procedure.function.asyncMarker,
- dartAsyncMarker: procedure.function.dartAsyncMarker))
+ asyncMarker: _procedure.function.asyncMarker,
+ dartAsyncMarker: _procedure.function.dartAsyncMarker))
..fileOffset = fileOffset;
_extensionTearOff
@@ -783,6 +786,9 @@
if (patch is ProcedureBuilder) {
if (checkPatch(patch)) {
patch.actualOrigin = this;
+ if (retainDataForTesting) {
+ patchForTesting = patch;
+ }
}
} else {
reportPatchMismatch(patch);
@@ -807,6 +813,8 @@
@override
ConstructorBuilder actualOrigin;
+ ConstructorBuilder patchForTesting;
+
Constructor get actualConstructor => _constructor;
ConstructorBuilder(
@@ -998,6 +1006,9 @@
if (patch is ConstructorBuilder) {
if (checkPatch(patch)) {
patch.actualOrigin = this;
+ if (retainDataForTesting) {
+ patchForTesting = patch;
+ }
}
} else {
reportPatchMismatch(patch);
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 f07de9d..7a7bc4c 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
@@ -150,10 +150,9 @@
/// [arguments] have already been built.
DartType buildTypesWithBuiltArguments(LibraryBuilder library,
Nullability nullability, List<DartType> arguments) {
- // TODO(dmitryas): Use [nullability].
DartType thisType = buildThisType(library);
if (const DynamicType() == thisType) return thisType;
- FunctionType result = thisType;
+ FunctionType result = thisType.withNullability(nullability);
if (typedef.typeParameters.isEmpty && arguments == null) return result;
Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
for (int i = 0; i < typedef.typeParameters.length; i++) {
@@ -209,8 +208,9 @@
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;
+ if (typedef.typeParameters.isEmpty && arguments == null) {
+ return thisType.withNullability(nullabilityBuilder.build(library));
+ }
// Otherwise, substitute.
return buildTypesWithBuiltArguments(
library,
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 93b1ade..ae2428b 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,6 +10,7 @@
import '../scope.dart';
import 'library_builder.dart';
+import 'nullability_builder.dart';
import 'type_declaration_builder.dart';
import 'type_variable_builder.dart';
@@ -32,6 +33,8 @@
/// May return null, for example, for mixin applications.
Object get name;
+ NullabilityBuilder get nullabilityBuilder;
+
String get debugName;
StringBuffer printOn(StringBuffer buffer);
@@ -65,4 +68,6 @@
Supertype buildMixedInType(
LibraryBuilder library, int charOffset, Uri fileUri);
+
+ TypeBuilder withNullabilityBuilder(NullabilityBuilder nullabilityBuilder);
}
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
index b46cd36..d45a8c7 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
@@ -26,7 +26,7 @@
bool get isStatic => _descriptor.isStatic;
@override
- bool get isExternal => _descriptor.isExternal;
+ bool get isExternal => member.isExternal;
@override
Procedure get procedure {
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 ad6ebd4..34eb285 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -161,12 +161,9 @@
DartType _type,
DartType
_type2)> templateArgumentTypeNotAssignable = const Template<
- Message Function(DartType _type,
- DartType _type2)>(
+ Message Function(DartType _type, DartType _type2)>(
messageTemplate:
r"""The argument type '#type' can't be assigned to the parameter type '#type2'.""",
- tipTemplate:
- r"""Try changing the type of the parameter, or casting the argument to '#type2'.""",
withArguments: _withArgumentsArgumentTypeNotAssignable);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -188,7 +185,6 @@
message:
"""The argument type '${type}' can't be assigned to the parameter type '${type2}'.""" +
labeler.originMessages,
- tip: """Try changing the type of the parameter, or casting the argument to '${type2}'.""",
arguments: {'type': _type, 'type2': _type2});
}
@@ -422,7 +418,6 @@
const Template<Message Function(Token token)>(
messageTemplate:
r"""The built-in identifier '#lexeme' can't be used as a type.""",
- tipTemplate: r"""Try correcting the name to match an existing type.""",
withArguments: _withArgumentsBuiltInIdentifierAsType);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -437,7 +432,6 @@
return new Message(codeBuiltInIdentifierAsType,
message:
"""The built-in identifier '${lexeme}' can't be used as a type.""",
- tip: """Try correcting the name to match an existing type.""",
arguments: {'token': token});
}
@@ -770,7 +764,7 @@
"CantUsePrefixWithNullAware",
analyzerCodes: <String>["PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT"],
message: r"""A prefix can't be used with null-aware operators.""",
- tip: r"""It should be safe to remove the '?' as a prefix is never null.""");
+ tip: r"""Try replacing '?.' with '.'""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeCatchSyntax = messageCatchSyntax;
@@ -1771,7 +1765,7 @@
Message Function(String name)>(
messageTemplate: r"""The const variable '#name' must be initialized.""",
tipTemplate:
- r"""Try adding an initializer ('= <expression>') to the declaration.""",
+ r"""Try adding an initializer ('= expression') to the declaration.""",
withArguments: _withArgumentsConstFieldWithoutInitializer);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1786,8 +1780,7 @@
name = demangleMixinApplicationName(name);
return new Message(codeConstFieldWithoutInitializer,
message: """The const variable '${name}' must be initialized.""",
- tip:
- """Try adding an initializer ('= <expression>') to the declaration.""",
+ tip: """Try adding an initializer ('= expression') to the declaration.""",
arguments: {'name': name});
}
@@ -2909,8 +2902,8 @@
"EqualityCannotBeEqualityOperand",
index: 1,
message:
- r"""An equality expression can't be an operand of another equality expression.""",
- tip: r"""Try re-writing the expression.""");
+ r"""A comparison expression can't be an operand of another comparison expression.""",
+ tip: r"""Try putting parentheses around one of the comparisons.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string)> templateExpectedAfterButGot =
@@ -3469,6 +3462,32 @@
tip: r"""Try removing the field declaration or making it a static field""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateExtensionMemberConflictsWithObjectMember =
+ const Template<Message Function(String name)>(
+ messageTemplate:
+ r"""This extension member conflicts with Object member '#name'.""",
+ withArguments: _withArgumentsExtensionMemberConflictsWithObjectMember);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+ codeExtensionMemberConflictsWithObjectMember =
+ const Code<Message Function(String name)>(
+ "ExtensionMemberConflictsWithObjectMember",
+ templateExtensionMemberConflictsWithObjectMember,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsExtensionMemberConflictsWithObjectMember(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeExtensionMemberConflictsWithObjectMember,
+ message:
+ """This extension member conflicts with Object member '${name}'.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeExternalClass = messageExternalClass;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3539,7 +3558,8 @@
const MessageCode messageExternalField = const MessageCode("ExternalField",
index: 50,
message: r"""Fields can't be declared to be 'external'.""",
- tip: r"""Try removing the keyword 'external'.""");
+ tip:
+ r"""Try removing the keyword 'external', or replacing the field by an external getter and/or setter.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeExternalMethodWithBody = messageExternalMethodWithBody;
@@ -4103,7 +4123,7 @@
const MessageCode messageFieldInitializedOutsideDeclaringClass = const MessageCode(
"FieldInitializedOutsideDeclaringClass",
index: 88,
- message: r"""A field can only be initialized in it's declaring class""",
+ message: r"""A field can only be initialized in its declaring class""",
tip:
r"""Try passing a value into the superclass constructor, or moving the initialization into the constructor body.""");
@@ -4206,7 +4226,7 @@
Message Function(String name)>(
messageTemplate: r"""The final variable '#name' must be initialized.""",
tipTemplate:
- r"""Try adding an initializer ('= <expression>') to the declaration.""",
+ r"""Try adding an initializer ('= expression') to the declaration.""",
withArguments: _withArgumentsFinalFieldWithoutInitializer);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4221,8 +4241,7 @@
name = demangleMixinApplicationName(name);
return new Message(codeFinalFieldWithoutInitializer,
message: """The final variable '${name}' must be initialized.""",
- tip:
- """Try adding an initializer ('= <expression>') to the declaration.""",
+ tip: """Try adding an initializer ('= expression') to the declaration.""",
arguments: {'name': name});
}
@@ -4423,7 +4442,7 @@
templateGenericFunctionTypeInferredAsActualTypeArgument =
const Template<Message Function(DartType _type)>(
messageTemplate:
- r"""Unexpected generic function type '#type' inferred as a type argument.""",
+ r"""Generic function type '#type' inferred as a type argument.""",
tipTemplate:
r"""Try providing a non-generic function type explicitly.""",
withArguments:
@@ -4445,7 +4464,7 @@
String type = typeParts.join();
return new Message(codeGenericFunctionTypeInferredAsActualTypeArgument,
message:
- """Unexpected generic function type '${type}' inferred as a type argument.""" +
+ """Generic function type '${type}' inferred as a type argument.""" +
labeler.originMessages,
tip: """Try providing a non-generic function type explicitly.""",
arguments: {'type': _type});
@@ -4460,7 +4479,7 @@
const MessageCode("GenericFunctionTypeUsedAsActualTypeArgument",
analyzerCodes: <String>["GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT"],
message:
- r"""Unexpected generic function type found in a type argument.""",
+ r"""A generic function type can't be used as a type argument.""",
tip: r"""Try using a non-generic function type.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6145,8 +6164,6 @@
Message Function(DartType _type, DartType _type2)>(
messageTemplate:
r"""A value of type '#type' can't be assigned to a variable of type '#type2'.""",
- tipTemplate:
- r"""Try changing the type of the left hand side, or casting the right hand side to '#type2'.""",
withArguments: _withArgumentsInvalidAssignment);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6167,7 +6184,6 @@
message:
"""A value of type '${type}' can't be assigned to a variable of type '${type2}'.""" +
labeler.originMessages,
- tip: """Try changing the type of the left hand side, or casting the right hand side to '${type2}'.""",
arguments: {'type': _type, 'type2': _type2});
}
@@ -6659,8 +6675,7 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageInvalidVoid = const MessageCode("InvalidVoid",
analyzerCodes: <String>["EXPECTED_TYPE_NAME"],
- message:
- r"""Type 'void' can't be used here because it isn't a return type.""",
+ message: r"""Type 'void' can't be used here.""",
tip:
r"""Try removing 'void' keyword or replace it with 'var', 'final', or a type.""");
@@ -6935,7 +6950,7 @@
const MessageCode messageMissingAssignableSelector = const MessageCode(
"MissingAssignableSelector",
index: 35,
- message: r"""Missing selector such as '.<identifier>' or '[0]'.""",
+ message: r"""Missing selector such as '.identifier' or '[0]'.""",
tip: r"""Try adding a selector.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7162,7 +7177,7 @@
"MissingPrefixInDeferredImport",
index: 30,
message: r"""Deferred imports should have a prefix.""",
- tip: r"""Try adding a prefix to the import.""");
+ tip: r"""Try adding a prefix to the import by adding an 'as' clause.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMissingTypedefParameters = messageMissingTypedefParameters;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 43af7e5..61e208b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -9,11 +9,9 @@
import 'package:front_end/src/fasta/dill/dill_class_builder.dart'
show DillClassBuilder;
-import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-
import 'package:kernel/binary/ast_from_binary.dart'
show
- BinaryBuilder,
+ BinaryBuilderWithMetadata,
CanonicalNameError,
CanonicalNameSdkError,
InvalidKernelVersionError;
@@ -730,7 +728,7 @@
if (summaryBytes != null) {
ticker.logMs("Read ${c.options.sdkSummary}");
data.component = c.options.target.configureComponent(new Component());
- new BinaryBuilder(summaryBytes,
+ new BinaryBuilderWithMetadata(summaryBytes,
disableLazyReading: false, disableLazyClassReading: true)
.readComponent(data.component);
ticker.logMs("Deserialized ${c.options.sdkSummary}");
@@ -755,7 +753,8 @@
// We're going to output all we read here so lazy loading it
// doesn't make sense.
- new BinaryBuilder(initializationBytes, disableLazyReading: true)
+ new BinaryBuilderWithMetadata(initializationBytes,
+ disableLazyReading: true)
.readComponent(data.component, checkCanonicalNames: true);
// Check the any package-urls still point to the same 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 656b1ae..6d6ca44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -7,6 +7,7 @@
import 'dart:core' hide MapEntry;
import 'package:kernel/ast.dart';
+import 'package:kernel/type_environment.dart';
import '../builder/declaration_builder.dart';
@@ -826,59 +827,9 @@
body, transformSetLiterals, transformCollections);
}
- // For async, async*, and sync* functions with declared return types, we
- // need to determine whether those types are valid.
if (builder.returnType != null) {
- DartType returnType = builder.function.returnType;
- // We use the same trick in each case below. For example to decide whether
- // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
- // transitivity of the subtyping relation because Future<Bot> <: Future<T>
- // for every T.
-
- // We use [problem == null] to signal success.
- Message problem;
- switch (asyncModifier) {
- case AsyncMarker.Async:
- DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
- if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType)) {
- problem = fasta.messageIllegalAsyncReturnType;
- }
- break;
-
- case AsyncMarker.AsyncStar:
- DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
- if (returnType is VoidType) {
- problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
- } else if (!typeEnvironment.isSubtypeOf(
- streamBottomType, returnType)) {
- problem = fasta.messageIllegalAsyncGeneratorReturnType;
- }
- break;
-
- case AsyncMarker.SyncStar:
- DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
- if (returnType is VoidType) {
- problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
- } else if (!typeEnvironment.isSubtypeOf(
- iterableBottomType, returnType)) {
- problem = fasta.messageIllegalSyncGeneratorReturnType;
- }
- break;
-
- case AsyncMarker.Sync:
- break; // skip
- case AsyncMarker.SyncYielding:
- unexpected("async, async*, sync, or sync*", "$asyncModifier",
- member.charOffset, uri);
- break;
- }
-
- if (problem != null) {
- // TODO(hillerstrom): once types get annotated with location
- // information, we can improve the quality of the error message by
- // using the offset of [returnType] (and the length of its name).
- addProblem(problem, member.charOffset, member.name.length);
- }
+ checkAsyncReturnType(asyncModifier, builder.function.returnType,
+ member.charOffset, member.name.length);
}
if (builder.kind == ProcedureKind.Setter) {
@@ -947,6 +898,62 @@
finishVariableMetadata();
}
+ void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
+ int charOffset, int length) {
+ // For async, async*, and sync* functions with declared return types, we
+ // need to determine whether those types are valid.
+ // We use the same trick in each case below. For example to decide whether
+ // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
+ // transitivity of the subtyping relation because Future<Bot> <: Future<T>
+ // for every T.
+
+ // We use [problem == null] to signal success.
+ Message problem;
+ switch (asyncModifier) {
+ case AsyncMarker.Async:
+ DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
+ if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType,
+ SubtypeCheckMode.ignoringNullabilities)) {
+ problem = fasta.messageIllegalAsyncReturnType;
+ }
+ break;
+
+ case AsyncMarker.AsyncStar:
+ DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
+ if (returnType is VoidType) {
+ problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
+ } else if (!typeEnvironment.isSubtypeOf(streamBottomType, returnType,
+ SubtypeCheckMode.ignoringNullabilities)) {
+ problem = fasta.messageIllegalAsyncGeneratorReturnType;
+ }
+ break;
+
+ case AsyncMarker.SyncStar:
+ DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
+ if (returnType is VoidType) {
+ problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
+ } else if (!typeEnvironment.isSubtypeOf(iterableBottomType, returnType,
+ SubtypeCheckMode.ignoringNullabilities)) {
+ problem = fasta.messageIllegalSyncGeneratorReturnType;
+ }
+ break;
+
+ case AsyncMarker.Sync:
+ break; // skip
+ case AsyncMarker.SyncYielding:
+ unexpected("async, async*, sync, or sync*", "$asyncModifier",
+ member.charOffset, uri);
+ break;
+ }
+
+ if (problem != null) {
+ // TODO(hillerstrom): once types get annotated with location
+ // information, we can improve the quality of the error message by
+ // using the offset of [returnType] (and the length of its name).
+ addProblem(problem, charOffset, length);
+ }
+ }
+
/// Ensure that the containing library of the [member] has been loaded.
///
/// This is for instance important for lazy dill library builders where this
@@ -4070,6 +4077,10 @@
}
FunctionDeclarationImpl.setHasImplicitReturnType(
declaration, hasImplicitReturnType);
+ if (!hasImplicitReturnType) {
+ checkAsyncReturnType(asyncModifier, function.returnType,
+ variable.fileOffset, variable.name.length);
+ }
variable.type = function.functionType;
if (isFunctionExpression) {
@@ -5036,7 +5047,8 @@
..fileOffset = assignmentOffset;
} else {
if (formalType != null &&
- !typeEnvironment.isSubtypeOf(formalType, builder.field.type)) {
+ !typeEnvironment.isSubtypeOf(formalType, builder.field.type,
+ SubtypeCheckMode.ignoringNullabilities)) {
libraryBuilder.addProblem(
fasta.templateInitializingFormalTypeMismatch
.withArguments(name, formalType, builder.field.type),
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 991fa4e..c588cd2 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
@@ -26,6 +26,7 @@
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart';
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
@@ -1997,8 +1998,9 @@
}
@override
- bool isSubtypeOf(DartType subtype, DartType supertype) {
- return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+ bool isSubtypeOf(
+ DartType subtype, DartType supertype, SubtypeCheckMode mode) {
+ return hierarchy.types.isSubtypeOfKernel(subtype, supertype, mode);
}
@override
@@ -2095,7 +2097,8 @@
if (a.hadTypesInferred) {
if (b.isSetter &&
(!impliesSetter(a) ||
- hierarchy.types.isSubtypeOfKernel(type, a.field.type))) {
+ hierarchy.types.isSubtypeOfKernel(type, a.field.type,
+ SubtypeCheckMode.ignoringNullabilities))) {
type = a.field.type;
} else {
reportCantInferFieldType(classBuilder, a);
@@ -2263,9 +2266,11 @@
bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
if (isSetter) {
- return hierarchy.types.isSubtypeOfKernel(b, a);
+ return hierarchy.types
+ .isSubtypeOfKernel(b, a, SubtypeCheckMode.ignoringNullabilities);
} else {
- return hierarchy.types.isSubtypeOfKernel(a, b);
+ return hierarchy.types
+ .isSubtypeOfKernel(a, b, SubtypeCheckMode.ignoringNullabilities);
}
}
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 0821f5e..f477cee 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1858,7 +1858,8 @@
}
}
}
- return typeEnvironment.isSubtypeOf(constantType, type);
+ return typeEnvironment.isSubtypeOf(
+ constantType, type, SubtypeCheckMode.ignoringNullabilities);
}
Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
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 e1f4092..2a22a37 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -1961,10 +1961,12 @@
List<DartType> explicitTypeArguments,
int extensionTypeParameterCount,
{bool isNullAware}) {
+ assert(getterBuilder != null || setterBuilder != null);
String targetName;
Procedure readTarget;
Procedure invokeTarget;
if (getterBuilder != null) {
+ assert(!getterBuilder.isStatic);
if (getterBuilder is AccessErrorBuilder) {
AccessErrorBuilder error = getterBuilder;
getterBuilder = error.builder;
@@ -1989,12 +1991,21 @@
}
}
Procedure writeTarget;
- if (setterBuilder is AccessErrorBuilder) {
- targetName ??= setterBuilder.name;
- } else if (setterBuilder != null && setterBuilder.isSetter) {
- MemberBuilder memberBuilder = setterBuilder;
- writeTarget = memberBuilder.member;
- targetName ??= memberBuilder.name;
+ if (setterBuilder != null) {
+ assert(!setterBuilder.isStatic);
+ if (setterBuilder is AccessErrorBuilder) {
+ targetName ??= setterBuilder.name;
+ } else if (setterBuilder.isSetter) {
+ MemberBuilder memberBuilder = setterBuilder;
+ writeTarget = memberBuilder.member;
+ targetName ??= memberBuilder.name;
+ } else {
+ return unhandled(
+ "${setterBuilder.runtimeType}",
+ "InstanceExtensionAccessGenerator.fromBuilder",
+ offsetForToken(token),
+ helper.uri);
+ }
}
return new ExplicitExtensionInstanceAccessGenerator(
helper,
@@ -2554,10 +2565,16 @@
return _makeInvalidRead();
}
- Generator _createInstanceAccess(Name name, {bool isNullAware}) {
+ Generator _createInstanceAccess(Token token, Name name, {bool isNullAware}) {
Builder getter = extensionBuilder.lookupLocalMember(name.name);
+ if (getter != null && getter.isStatic) {
+ getter = null;
+ }
Builder setter =
extensionBuilder.lookupLocalMember(name.name, setter: true);
+ if (setter != null && setter.isStatic) {
+ setter = null;
+ }
if (getter == null && setter == null) {
return new UnresolvedNameGenerator(_helper, token, name);
}
@@ -2580,7 +2597,7 @@
messageNotAConstantExpression, fileOffset, token.length);
}
Generator generator =
- _createInstanceAccess(send.name, isNullAware: isNullAware);
+ _createInstanceAccess(send.token, send.name, isNullAware: isNullAware);
if (send.arguments != null) {
return generator.doInvocation(offsetForToken(send.token), send.arguments);
} else {
@@ -2590,7 +2607,8 @@
@override
doInvocation(int offset, Arguments arguments) {
- Generator generator = _createInstanceAccess(callName, isNullAware: false);
+ Generator generator =
+ _createInstanceAccess(token, callName, isNullAware: false);
return generator.doInvocation(offset, arguments);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 3c7ea2e..99e4ad8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -5,7 +5,7 @@
library fasta.implicit_type;
import 'package:kernel/ast.dart'
- show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+ show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
import '../../scanner/token.dart' show Token;
@@ -18,11 +18,11 @@
Token initializerToken;
bool isStarted = false;
- get nullability =>
- unsupported("nullability", member.charOffset, member.fileUri);
-
ImplicitFieldType(this.member, this.initializerToken);
+ Nullability get nullability =>
+ unsupported("nullability", member.charOffset, member.fileUri);
+
R accept<R>(DartTypeVisitor<R> v) {
throw unsupported("accept", member.charOffset, member.fileUri);
}
@@ -34,4 +34,8 @@
visitChildren(Visitor<Object> v) {
unsupported("visitChildren", member.charOffset, member.fileUri);
}
+
+ ImplicitFieldType withNullability(Nullability nullability) {
+ return unsupported("withNullability", member.charOffset, member.fileUri);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 6cb9d18..e9a98e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -5,7 +5,7 @@
library fasta.implicit_type_argument;
import 'package:kernel/ast.dart'
- show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+ show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
import '../problems.dart' show unhandled, unsupported;
@@ -18,7 +18,7 @@
const ImplicitTypeArgument();
@override
- get nullability => unsupported("nullability", -1, null);
+ Nullability get nullability => unsupported("nullability", -1, null);
@override
R accept<R>(DartTypeVisitor<R> v) {
@@ -34,4 +34,9 @@
visitChildren(Visitor<Object> v) {
unhandled("$runtimeType", "${v.runtimeType}", -1, null);
}
+
+ @override
+ ImplicitTypeArgument withNullability(Nullability nullability) {
+ return unsupported("withNullability", -1, null);
+ }
}
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 816cc1e..c1b4dc0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -366,12 +366,9 @@
}
bool hasExplicitTypeArguments =
getExplicitTypeArguments(node.arguments) != null;
- DartType inferredType = inferrer.inferInvocation(
- typeContext,
- node.fileOffset,
- node.target.function.thisFunctionType,
- computeConstructorReturnType(node.target),
- node.arguments,
+ DartType inferredType = inferrer.inferInvocation(typeContext,
+ node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+ returnType: computeConstructorReturnType(node.target),
isConst: node.isConst);
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
@@ -396,8 +393,8 @@
: new FunctionType([], const DynamicType());
bool hadExplicitTypeArguments =
getExplicitTypeArguments(node.arguments) != null;
- DartType inferredType = inferrer.inferInvocation(typeContext,
- node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+ DartType inferredType = inferrer.inferInvocation(
+ typeContext, node.fileOffset, calleeType, node.arguments);
Expression replacement = new StaticInvocation(node.target, node.arguments);
if (!inferrer.isTopLevel &&
!hadExplicitTypeArguments &&
@@ -531,12 +528,9 @@
FactoryConstructorInvocationJudgment node, DartType typeContext) {
bool hadExplicitTypeArguments =
getExplicitTypeArguments(node.arguments) != null;
- DartType inferredType = inferrer.inferInvocation(
- typeContext,
- node.fileOffset,
- node.target.function.thisFunctionType,
- computeConstructorReturnType(node.target),
- node.arguments,
+ DartType inferredType = inferrer.inferInvocation(typeContext,
+ node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+ returnType: computeConstructorReturnType(node.target),
isConst: node.isConst);
node.hasBeenInferred = true;
if (!inferrer.isTopLevel) {
@@ -795,8 +789,8 @@
node.fileOffset,
substitution.substituteType(
node.target.function.thisFunctionType.withoutTypeParameters),
- inferrer.thisType,
node.argumentsJudgment,
+ returnType: inferrer.thisType,
skipTypeArgumentInference: true);
}
@@ -1386,9 +1380,13 @@
mapEntryClass, <DartType>[actualKeyType, actualValueType]);
bool isMap = inferrer.typeSchemaEnvironment.isSubtypeOf(
- spreadType, inferrer.coreTypes.mapRawType(inferrer.library.nullable));
- bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(spreadType,
- inferrer.coreTypes.iterableRawType(inferrer.library.nullable));
+ spreadType,
+ inferrer.coreTypes.mapRawType(inferrer.library.nullable),
+ SubtypeCheckMode.ignoringNullabilities);
+ bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(
+ spreadType,
+ inferrer.coreTypes.iterableRawType(inferrer.library.nullable),
+ SubtypeCheckMode.ignoringNullabilities);
if (isMap && !isIterable) {
mapSpreadOffset = entry.fileOffset;
}
@@ -4162,12 +4160,9 @@
typeArguments[i] = new TypeParameterType(classTypeParameters[i]);
}
ArgumentsImpl.setNonInferrableArgumentTypes(node.arguments, typeArguments);
- inferrer.inferInvocation(
- null,
- node.fileOffset,
- node.target.function.thisFunctionType,
- node.target.enclosingClass.thisType,
- node.arguments,
+ inferrer.inferInvocation(null, node.fileOffset,
+ node.target.function.thisFunctionType, node.arguments,
+ returnType: node.target.enclosingClass.thisType,
skipTypeArgumentInference: true);
ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
}
@@ -4313,8 +4308,8 @@
: new FunctionType([], const DynamicType());
bool hadExplicitTypeArguments =
getExplicitTypeArguments(node.arguments) != null;
- DartType inferredType = inferrer.inferInvocation(typeContext,
- node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+ DartType inferredType = inferrer.inferInvocation(
+ typeContext, node.fileOffset, calleeType, node.arguments);
if (!inferrer.isTopLevel &&
!hadExplicitTypeArguments &&
node.target != null) {
@@ -4356,8 +4351,8 @@
node.fileOffset,
substitution.substituteType(
node.target.function.thisFunctionType.withoutTypeParameters),
- inferrer.thisType,
node.arguments,
+ returnType: inferrer.thisType,
skipTypeArgumentInference: true);
}
@@ -4620,8 +4615,8 @@
inferrer.typeSchemaEnvironment.futureType(const DynamicType());
if (node.arguments != null) {
FunctionType calleeType = new FunctionType([], inferredType);
- inferrer.inferInvocation(typeContext, node.fileOffset, calleeType,
- calleeType.returnType, node.arguments);
+ inferrer.inferInvocation(
+ typeContext, node.fileOffset, calleeType, node.arguments);
}
return new ExpressionInferenceResult(inferredType);
}
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 627fbc5..e1dbaf4 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/type_environment.dart';
+
import 'package:kernel/clone.dart';
import '../../base/instrumentation.dart'
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index 6e519f9..0e7d4d4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -46,7 +46,8 @@
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+ show SubtypeCheckMode, TypeEnvironment;
import 'package:kernel/visitor.dart' show Transformer;
@@ -248,7 +249,8 @@
VariableDeclaration elt;
Statement loopBody;
if (element.elementType == null ||
- !typeEnvironment.isSubtypeOf(element.elementType, elementType)) {
+ !typeEnvironment.isSubtypeOf(element.elementType, elementType,
+ SubtypeCheckMode.ignoringNullabilities)) {
elt = new VariableDeclaration(null,
type: const DynamicType(), isFinal: true);
VariableDeclaration castedVar = new VariableDeclaration.forValue(
@@ -439,7 +441,8 @@
VariableDeclaration elt;
Statement loopBody;
if (entry.entryType == null ||
- !typeEnvironment.isSubtypeOf(entry.entryType, entryType)) {
+ !typeEnvironment.isSubtypeOf(entry.entryType, entryType,
+ SubtypeCheckMode.ignoringNullabilities)) {
elt = new VariableDeclaration(null,
type: new InterfaceType(mapEntryClass,
<DartType>[const DynamicType(), const DynamicType()]),
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 544ff1d..bcceaad 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -120,6 +120,29 @@
return Variance.unrelated;
}
+/// Combines syntactic nullabilities on types for performing type substitution.
+///
+/// The syntactic substitution should preserve a `?` if it was either on the
+/// type parameter occurrence or on the type argument replacing it.
+NullabilityBuilder combineNullabilityBuildersForSubstitution(
+ NullabilityBuilder a, NullabilityBuilder b) {
+ assert(
+ (identical(a, const NullabilityBuilder.nullable()) ||
+ identical(a, const NullabilityBuilder.omitted())) &&
+ (identical(b, const NullabilityBuilder.nullable()) ||
+ identical(b, const NullabilityBuilder.omitted())),
+ "Both arguments to combineNullabilityBuildersForSubstitution "
+ "should be identical to either 'const NullabilityBuilder.nullable()' or "
+ "'const NullabilityBuilder.omitted()'.");
+
+ if (identical(a, const NullabilityBuilder.nullable()) ||
+ identical(b, const NullabilityBuilder.nullable())) {
+ return const NullabilityBuilder.nullable();
+ }
+
+ return const NullabilityBuilder.omitted();
+}
+
TypeBuilder substituteRange(
TypeBuilder type,
Map<TypeVariableBuilder, TypeBuilder> upperSubstitution,
@@ -130,9 +153,21 @@
if (type is NamedTypeBuilder) {
if (type.declaration is TypeVariableBuilder) {
if (variance == Variance.contravariant) {
- return lowerSubstitution[type.declaration] ?? type;
+ TypeBuilder replacement = lowerSubstitution[type.declaration];
+ if (replacement != null) {
+ return replacement.withNullabilityBuilder(
+ combineNullabilityBuildersForSubstitution(
+ replacement.nullabilityBuilder, type.nullabilityBuilder));
+ }
+ return type;
}
- return upperSubstitution[type.declaration] ?? type;
+ TypeBuilder replacement = upperSubstitution[type.declaration];
+ if (replacement != null) {
+ return replacement.withNullabilityBuilder(
+ combineNullabilityBuildersForSubstitution(
+ replacement.nullabilityBuilder, type.nullabilityBuilder));
+ }
+ return type;
}
if (type.arguments == null || type.arguments.length == 0) {
return type;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 45d0275..0bb51ac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -178,6 +178,7 @@
result.add(" extends ");
param.bound.accept(this);
}
+ first = false;
}
result.add(">");
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
index a70d416..bf19015 100644
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -22,6 +22,8 @@
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart';
+
import 'kernel_builder.dart' show ClassHierarchyBuilder;
class Types {
@@ -30,7 +32,7 @@
Types(this.hierarchy);
/// Returns true if [s] is a subtype of [t].
- bool isSubtypeOfKernel(DartType s, DartType t) {
+ bool isSubtypeOfKernel(DartType s, DartType t, SubtypeCheckMode mode) {
if (s is InvalidType) {
// InvalidType is a bottom type.
return true;
@@ -231,13 +233,15 @@
throw "Numbers of type arguments don't match $s $t.";
}
for (int i = 0; i < s.length; i++) {
- if (!isSubtypeOfKernel(s[i], t[i])) return false;
+ if (!isSubtypeOfKernel(
+ s[i], t[i], SubtypeCheckMode.ignoringNullabilities)) return false;
}
return true;
}
bool isSameTypeKernel(DartType s, DartType t) {
- return isSubtypeOfKernel(s, t) && isSubtypeOfKernel(t, s);
+ return isSubtypeOfKernel(s, t, SubtypeCheckMode.ignoringNullabilities) &&
+ isSubtypeOfKernel(t, s, SubtypeCheckMode.ignoringNullabilities);
}
}
@@ -301,7 +305,8 @@
@override
bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
InterfaceType t, Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s.parameter.bound, t);
+ return types.isSubtypeOfKernel(
+ s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -312,11 +317,14 @@
Nullability tNullability,
Types types) {
List<DartType> arguments = futureOr.typeArguments;
- if (!types.isSubtypeOfKernel(arguments.single, t)) {
+ if (!types.isSubtypeOfKernel(
+ arguments.single, t, SubtypeCheckMode.ignoringNullabilities)) {
return false; // Rule 7.1
}
if (!types.isSubtypeOfKernel(
- new InterfaceType(types.hierarchy.futureClass, arguments), t)) {
+ new InterfaceType(types.hierarchy.futureClass, arguments),
+ t,
+ SubtypeCheckMode.ignoringNullabilities)) {
return false; // Rule 7.2
}
return true;
@@ -329,7 +337,8 @@
InterfaceType t,
Nullability tNullability,
Types types) {
- return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
+ return types.isSubtypeOfKernel(intersection.promotedBound, t,
+ SubtypeCheckMode.ignoringNullabilities); // Rule 12.
}
@override
@@ -348,7 +357,8 @@
bool isTypedefRelated(TypedefType s, Nullability sNullability,
InterfaceType t, Nullability tNullability, Types types) {
// Rule 5.
- return types.isSubtypeOfKernel(s.unalias, t);
+ return types.isSubtypeOfKernel(
+ s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -397,7 +407,10 @@
}
s = substitution.substituteType(s.withoutTypeParameters);
}
- if (!types.isSubtypeOfKernel(s.returnType, t.returnType)) return false;
+ if (!types.isSubtypeOfKernel(
+ s.returnType, t.returnType, SubtypeCheckMode.ignoringNullabilities)) {
+ return false;
+ }
List<DartType> sPositional = s.positionalParameters;
List<DartType> tPositional = t.positionalParameters;
if (s.requiredParameterCount > t.requiredParameterCount) {
@@ -409,7 +422,8 @@
return false;
}
for (int i = 0; i < tPositional.length; i++) {
- if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i])) {
+ if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i],
+ SubtypeCheckMode.ignoringNullabilities)) {
// Rule 15, Tj <: Sj.
return false;
}
@@ -431,8 +445,8 @@
if (sNamed[sCount].name == name) break;
}
if (sCount == sNamed.length) return false;
- if (!types.isSubtypeOfKernel(
- tNamed[tCount].type, sNamed[sCount].type)) {
+ if (!types.isSubtypeOfKernel(tNamed[tCount].type, sNamed[sCount].type,
+ SubtypeCheckMode.ignoringNullabilities)) {
return false;
}
}
@@ -470,21 +484,24 @@
Nullability tNullability,
Types types) {
// Rule 12.
- return types.isSubtypeOfKernel(intersection.promotedBound, t);
+ return types.isSubtypeOfKernel(
+ intersection.promotedBound, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
FunctionType t, Nullability tNullability, Types types) {
// Rule 13.
- return types.isSubtypeOfKernel(s.parameter.bound, t);
+ return types.isSubtypeOfKernel(
+ s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
Nullability tNullability, Types types) {
// Rule 5.
- return types.isSubtypeOfKernel(s.unalias, t);
+ return types.isSubtypeOfKernel(
+ s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -502,7 +519,8 @@
TypeParameterType t, Nullability tNullability, Types types) {
return s.parameter == t.parameter ||
// Rule 13.
- types.isSubtypeOfKernel(s.bound, t);
+ types.isSubtypeOfKernel(
+ s.bound, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -546,7 +564,8 @@
@override
bool isTypedefRelated(TypedefType s, Nullability sNullability,
TypeParameterType t, Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s.unalias, t);
+ return types.isSubtypeOfKernel(
+ s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -562,19 +581,22 @@
@override
bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
TypedefType t, Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s, t.unalias);
+ return types.isSubtypeOfKernel(
+ s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s, t.unalias);
+ return types.isSubtypeOfKernel(
+ s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isFunctionRelated(FunctionType s, Nullability sNullability,
TypedefType t, Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s, t.unalias);
+ return types.isSubtypeOfKernel(
+ s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -584,7 +606,8 @@
TypedefType t,
Nullability tNullability,
Types types) {
- return types.isSubtypeOfKernel(futureOr, t.unalias);
+ return types.isSubtypeOfKernel(
+ futureOr, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -594,25 +617,29 @@
TypedefType t,
Nullability tNullability,
Types types) {
- return types.isSubtypeOfKernel(intersection, t.unalias);
+ return types.isSubtypeOfKernel(
+ intersection, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
TypedefType t, Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s, t.unalias);
+ return types.isSubtypeOfKernel(
+ s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s.unalias, t.unalias);
+ return types.isSubtypeOfKernel(
+ s.unalias, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
Nullability tNullability, Types types) {
- return types.isSubtypeOfKernel(s, t.unalias);
+ return types.isSubtypeOfKernel(
+ s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
}
}
@@ -623,12 +650,15 @@
bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
List<DartType> arguments = futureOr.typeArguments;
- if (types.isSubtypeOfKernel(s, arguments.single)) {
+ if (types.isSubtypeOfKernel(
+ s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
return true; // Rule 11.
}
// Rule 10.
return types.isSubtypeOfKernel(
- s, new InterfaceType(types.hierarchy.futureClass, arguments));
+ s,
+ new InterfaceType(types.hierarchy.futureClass, arguments),
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -639,48 +669,55 @@
Nullability tFutureOrNullability,
Types types) {
// This follows from combining rules 7, 10, and 11.
- return types.isSubtypeOfKernel(
- sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
+ return types.isSubtypeOfKernel(sFutureOr.typeArguments.single,
+ tFutureOr.typeArguments.single, SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isDynamicRelated(DynamicType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
- return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+ return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isVoidRelated(VoidType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
- return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+ return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
List<DartType> arguments = futureOr.typeArguments;
- if (types.isSubtypeOfKernel(s, arguments.single)) {
+ if (types.isSubtypeOfKernel(
+ s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
// Rule 11.
return true;
}
- if (types.isSubtypeOfKernel(s.parameter.bound, futureOr)) {
+ if (types.isSubtypeOfKernel(
+ s.parameter.bound, futureOr, SubtypeCheckMode.ignoringNullabilities)) {
// Rule 13.
return true;
}
// Rule 10.
return types.isSubtypeOfKernel(
- s, new InterfaceType(types.hierarchy.futureClass, arguments));
+ s,
+ new InterfaceType(types.hierarchy.futureClass, arguments),
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isFunctionRelated(FunctionType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
// Rule 11.
- return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+ return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -696,13 +733,15 @@
return true;
}
// Rule 12.
- return types.isSubtypeOfKernel(intersection.promotedBound, futureOr);
+ return types.isSubtypeOfKernel(intersection.promotedBound, futureOr,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
bool isTypedefRelated(TypedefType s, Nullability sNullability,
InterfaceType futureOr, Nullability futureOrNullability, Types types) {
- return types.isSubtypeOfKernel(s.unalias, futureOr);
+ return types.isSubtypeOfKernel(
+ s.unalias, futureOr, SubtypeCheckMode.ignoringNullabilities);
}
}
@@ -723,7 +762,8 @@
tIntersection,
tIntersectionNullability,
types) &&
- types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
+ types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -736,7 +776,8 @@
// Rule 9.
return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
s, sNullability, intersection, intersectionNullability, types) &&
- types.isSubtypeOfKernel(s, intersection.promotedBound);
+ types.isSubtypeOfKernel(s, intersection.promotedBound,
+ SubtypeCheckMode.ignoringNullabilities);
}
@override
@@ -787,7 +828,8 @@
Nullability intersectionNullability,
Types types) {
// Rule 5.
- return types.isSubtypeOfKernel(s.unalias, intersection);
+ return types.isSubtypeOfKernel(
+ s.unalias, intersection, SubtypeCheckMode.ignoringNullabilities);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index f2753bd..9e548fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -3444,7 +3444,7 @@
beforeInitializers?.next, token);
break;
case DeclarationKind.Extension:
- if (optional(';', bodyStart)) {
+ if (optional(';', bodyStart) && externalToken == null) {
reportRecoverableError(isOperator ? name.next : name,
fasta.messageExtensionDeclaresAbstractMember);
}
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 fd7df17..09ac319 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
@@ -4,6 +4,7 @@
import 'dart:core' hide MapEntry;
import 'package:kernel/ast.dart';
+import '../../base/common.dart';
import '../builder/declaration.dart';
import '../builder/extension_builder.dart';
import '../builder/library_builder.dart';
@@ -12,22 +13,26 @@
import '../builder/type_builder.dart';
import '../builder/type_variable_builder.dart';
import '../scope.dart';
-import 'source_library_builder.dart';
import '../kernel/kernel_builder.dart';
-
import '../problems.dart';
-
import '../fasta_codes.dart'
show
+ messagePatchDeclarationMismatch,
+ messagePatchDeclarationOrigin,
noLength,
templateConflictsWithMember,
templateConflictsWithMemberWarning,
templateConflictsWithSetter,
- templateConflictsWithSetterWarning;
+ templateConflictsWithSetterWarning,
+ templateExtensionMemberConflictsWithObjectMember;
+import 'source_library_builder.dart';
class SourceExtensionBuilder extends ExtensionBuilder {
final Extension _extension;
+ SourceExtensionBuilder _origin;
+ SourceExtensionBuilder patchForTesting;
+
SourceExtensionBuilder(
List<MetadataBuilder> metadata,
int modifiers,
@@ -48,7 +53,10 @@
super(metadata, modifiers, name, parent, nameOffset, scope,
typeParameters, onType);
- Extension get extension => _extension;
+ @override
+ SourceExtensionBuilder get origin => _origin ?? this;
+
+ Extension get extension => isPatch ? origin._extension : _extension;
/// Builds the [Extension] for this extension build and inserts the members
/// into the [Library] of [libraryBuilder].
@@ -61,8 +69,20 @@
Extension build(
SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary,
{bool addMembersToLibrary}) {
+ ClassBuilder objectClassBuilder =
+ coreLibrary.lookupLocalMember('Object', required: true);
void buildBuilders(String name, Builder declaration) {
do {
+ Builder objectGetter = objectClassBuilder.lookupLocalMember(name);
+ Builder objectSetter =
+ objectClassBuilder.lookupLocalMember(name, setter: true);
+ if (objectGetter != null || objectSetter != null) {
+ addProblem(
+ templateExtensionMemberConflictsWithObjectMember
+ .withArguments(name),
+ declaration.charOffset,
+ name.length);
+ }
if (declaration.parent != this) {
if (fileUri != declaration.parent.fileUri) {
unexpected("$fileUri", "${declaration.parent.fileUri}", charOffset,
@@ -75,7 +95,7 @@
Field field = declaration.build(libraryBuilder);
if (addMembersToLibrary && declaration.next == null) {
libraryBuilder.library.addMember(field);
- _extension.members.add(new ExtensionMemberDescriptor(
+ extension.members.add(new ExtensionMemberDescriptor(
name: new Name(declaration.name, libraryBuilder.library),
member: field.reference,
isStatic: declaration.isStatic,
@@ -83,7 +103,9 @@
}
} else if (declaration is ProcedureBuilder) {
Member function = declaration.build(libraryBuilder);
- if (addMembersToLibrary && declaration.next == null) {
+ if (addMembersToLibrary &&
+ !declaration.isPatch &&
+ declaration.next == null) {
libraryBuilder.library.addMember(function);
ExtensionMemberKind kind;
switch (declaration.kind) {
@@ -103,11 +125,10 @@
unsupported("Extension method kind: ${declaration.kind}",
declaration.charOffset, declaration.fileUri);
}
- _extension.members.add(new ExtensionMemberDescriptor(
+ 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) {
@@ -116,7 +137,6 @@
name: new Name(declaration.name, libraryBuilder.library),
member: tearOff.reference,
isStatic: false,
- isExternal: false,
kind: ExtensionMemberKind.TearOff));
}
}
@@ -157,4 +177,46 @@
return _extension;
}
+
+ @override
+ void applyPatch(Builder patch) {
+ if (patch is SourceExtensionBuilder) {
+ patch._origin = this;
+ if (retainDataForTesting) {
+ patchForTesting = patch;
+ }
+ scope.local.forEach((String name, Builder member) {
+ Builder memberPatch = patch.scope.local[name];
+ if (memberPatch != null) {
+ member.applyPatch(memberPatch);
+ }
+ });
+ scope.setters.forEach((String name, Builder member) {
+ Builder memberPatch = patch.scope.setters[name];
+ if (memberPatch != null) {
+ member.applyPatch(memberPatch);
+ }
+ });
+
+ // TODO(johnniwinther): Check that type parameters and on-type match
+ // with origin declaration.
+ } else {
+ library.addProblem(messagePatchDeclarationMismatch, patch.charOffset,
+ noLength, patch.fileUri, context: [
+ messagePatchDeclarationOrigin.withLocation(
+ fileUri, charOffset, noLength)
+ ]);
+ }
+ }
+
+ @override
+ int finishPatch() {
+ if (!isPatch) return 0;
+
+ int count = 0;
+ scope.forEach((String name, Builder declaration) {
+ count += declaration.finishPatch();
+ });
+ return count;
+ }
}
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 f2243b2..83ce151 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
@@ -20,6 +20,8 @@
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
import 'type_schema.dart' show UnknownType;
abstract class StandardBounds {
@@ -30,7 +32,7 @@
InterfaceType get objectLegacyRawType;
InterfaceType get functionLegacyRawType;
- bool isSubtypeOf(DartType subtype, DartType supertype);
+ bool isSubtypeOf(DartType subtype, DartType supertype, SubtypeCheckMode mode);
InterfaceType getLegacyLeastUpperBound(
InterfaceType type1, InterfaceType type2);
@@ -94,11 +96,11 @@
// Otherwise, the lower bounds of two types is one of them it if it is a
// subtype of the other.
- if (isSubtypeOf(type1, type2)) {
+ if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
return type1;
}
- if (isSubtypeOf(type2, type1)) {
+ if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
return type2;
}
@@ -408,10 +410,10 @@
// 3. Otherwise return the spec-defined standard upper bound. This will
// be an upper bound, might (or might not) be least, and might
// (or might not) be a well-formed type.
- if (isSubtypeOf(type1, type2)) {
+ if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
return type2;
}
- if (isSubtypeOf(type2, type1)) {
+ if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
return type1;
}
if (type1 is InterfaceType &&
@@ -463,10 +465,10 @@
// type variable first. Alternatively, you could probably choose to treat
// it as just an instance of the interface type upper bound problem, with
// the "inheritance" chain extended by the bounds placed on the variables.
- if (isSubtypeOf(type1, type2)) {
+ if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
return type2;
}
- if (isSubtypeOf(type2, type1)) {
+ if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
return type1;
}
if (type1 is TypeParameterType) {
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 faf4afd..e51fb8d 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
@@ -12,8 +12,9 @@
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/type_algebra.dart'
- show FreshTypeParameters, getFreshTypeParameters, Substitution;
+import 'package:kernel/type_algebra.dart';
+
+import 'package:kernel/type_environment.dart';
import 'package:kernel/src/bounds_checks.dart' show calculateBounds;
@@ -349,8 +350,8 @@
assert(_needToInferReturnType);
DartType inferredType =
inferrer.inferReturnType(_inferredUnwrappedReturnOrYieldType);
- if (!inferrer.typeSchemaEnvironment
- .isSubtypeOf(inferredType, returnOrYieldContext)) {
+ if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
+ returnOrYieldContext, SubtypeCheckMode.ignoringNullabilities)) {
// If the inferred return type isn't a subtype of the context, we use the
// context.
inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
@@ -525,8 +526,10 @@
}
bool isAssignable(DartType expectedType, DartType actualType) {
- return typeSchemaEnvironment.isSubtypeOf(expectedType, actualType) ||
- typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
+ return typeSchemaEnvironment.isSubtypeOf(
+ expectedType, actualType, SubtypeCheckMode.ignoringNullabilities) ||
+ typeSchemaEnvironment.isSubtypeOf(
+ actualType, expectedType, SubtypeCheckMode.ignoringNullabilities);
}
/// Checks whether [actualType] can be assigned to the greatest closure of
@@ -602,12 +605,14 @@
}
if (expectedType == null ||
- typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+ typeSchemaEnvironment.isSubtypeOf(
+ actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
// Types are compatible.
return null;
}
- if (!typeSchemaEnvironment.isSubtypeOf(expectedType, actualType)) {
+ if (!typeSchemaEnvironment.isSubtypeOf(
+ expectedType, actualType, SubtypeCheckMode.ignoringNullabilities)) {
// Error: not assignable. Perform error recovery.
TreeNode parent = expression.parent;
Expression errorNode = new AsExpression(
@@ -790,7 +795,8 @@
DartType typeArgument = inferredTypeArguments[index];
DartType bound =
inferredSubstitution.substituteType(typeParameter.bound);
- if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound)) {
+ if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound,
+ SubtypeCheckMode.ignoringNullabilities)) {
return;
}
}
@@ -805,7 +811,8 @@
.substituteType(extensionBuilder.extension.onType);
}
- if (typeSchemaEnvironment.isSubtypeOf(receiverType, onType)) {
+ if (typeSchemaEnvironment.isSubtypeOf(
+ receiverType, onType, SubtypeCheckMode.ignoringNullabilities)) {
ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
onType,
onTypeInstantiateToBounds,
@@ -1639,26 +1646,33 @@
}
DartType inferInvocation(DartType typeContext, int offset,
- FunctionType calleeType, DartType returnType, Arguments arguments,
+ FunctionType calleeType, Arguments arguments,
{bool isOverloadedArithmeticOperator: false,
+ DartType returnType,
DartType receiverType,
bool skipTypeArgumentInference: false,
bool isConst: false,
bool isImplicitExtensionMember: false}) {
+ assert(
+ returnType == null || !containsFreeFunctionTypeVariables(returnType),
+ "Return type $returnType contains free variables."
+ "Provided function type: $calleeType.");
int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
if (extensionTypeParameterCount != 0) {
+ assert(returnType == null,
+ "Unexpected explicit return type for extension method invocation.");
return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
- typeContext, offset, calleeType, returnType, arguments,
+ typeContext, offset, calleeType, arguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
receiverType: receiverType,
skipTypeArgumentInference: skipTypeArgumentInference,
isConst: isConst,
isImplicitExtensionMember: isImplicitExtensionMember);
}
- return _inferInvocation(
- typeContext, offset, calleeType, returnType, arguments,
+ return _inferInvocation(typeContext, offset, calleeType, arguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
receiverType: receiverType,
+ returnType: returnType,
skipTypeArgumentInference: skipTypeArgumentInference,
isConst: isConst,
isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1669,7 +1683,6 @@
DartType typeContext,
int offset,
FunctionType calleeType,
- DartType returnType,
Arguments arguments,
{bool isOverloadedArithmeticOperator: false,
DartType receiverType,
@@ -1685,8 +1698,8 @@
Arguments extensionArguments = helper.forest.createArguments(
arguments.fileOffset, [arguments.positional.first],
types: getExplicitExtensionTypeArguments(arguments));
- _inferInvocation(const UnknownType(), offset, extensionFunctionType,
- extensionFunctionType.returnType, extensionArguments,
+ _inferInvocation(
+ const UnknownType(), offset, extensionFunctionType, extensionArguments,
skipTypeArgumentInference: skipTypeArgumentInference,
receiverType: receiverType,
isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1705,13 +1718,11 @@
typeParameters: targetTypeParameters);
targetFunctionType =
extensionSubstitution.substituteType(targetFunctionType);
- DartType targetReturnType =
- extensionSubstitution.substituteType(returnType);
Arguments targetArguments = helper.forest.createArguments(
arguments.fileOffset, arguments.positional.skip(1).toList(),
named: arguments.named, types: getExplicitTypeArguments(arguments));
- DartType inferredType = _inferInvocation(typeContext, offset,
- targetFunctionType, targetReturnType, targetArguments,
+ DartType inferredType = _inferInvocation(
+ typeContext, offset, targetFunctionType, targetArguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
skipTypeArgumentInference: skipTypeArgumentInference,
isConst: isConst);
@@ -1731,13 +1742,18 @@
/// Performs the type inference steps that are shared by all kinds of
/// invocations (constructors, instance methods, and static methods).
DartType _inferInvocation(DartType typeContext, int offset,
- FunctionType calleeType, DartType returnType, Arguments arguments,
+ FunctionType calleeType, Arguments arguments,
{bool isOverloadedArithmeticOperator: false,
bool isBinaryOperator: false,
DartType receiverType,
+ DartType returnType,
bool skipTypeArgumentInference: false,
bool isConst: false,
bool isImplicitExtensionMember: false}) {
+ assert(
+ returnType == null || !containsFreeFunctionTypeVariables(returnType),
+ "Return type $returnType contains free variables."
+ "Provided function type: $calleeType.");
lastInferredSubstitution = null;
lastCalleeType = null;
List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
@@ -1753,7 +1769,9 @@
// in which me must do this, to avoid a performance regression?
FreshTypeParameters fresh = getFreshTypeParameters(calleeTypeParameters);
calleeType = fresh.applyToFunctionType(calleeType);
- returnType = fresh.substitute(returnType);
+ if (returnType != null) {
+ returnType = fresh.substitute(returnType);
+ }
calleeTypeParameters = fresh.freshTypeParameters;
}
List<DartType> explicitTypeArguments = getExplicitTypeArguments(arguments);
@@ -1776,8 +1794,13 @@
}
inferredTypes = new List<DartType>.filled(
calleeTypeParameters.length, const UnknownType());
- typeSchemaEnvironment.inferGenericFunctionOrType(returnType,
- calleeTypeParameters, null, null, typeContext, inferredTypes);
+ typeSchemaEnvironment.inferGenericFunctionOrType(
+ returnType ?? calleeType.returnType,
+ calleeTypeParameters,
+ null,
+ null,
+ typeContext,
+ inferredTypes);
substitution =
Substitution.fromPairs(calleeTypeParameters, inferredTypes);
} else if (explicitTypeArguments != null &&
@@ -1869,7 +1892,7 @@
if (inferenceNeeded) {
typeSchemaEnvironment.inferGenericFunctionOrType(
- returnType,
+ returnType ?? calleeType.returnType,
calleeTypeParameters,
formalTypes,
actualTypes,
@@ -1912,9 +1935,21 @@
DartType inferredType;
lastInferredSubstitution = substitution;
lastCalleeType = calleeType;
- inferredType = substitution == null
- ? returnType
- : substitution.substituteType(returnType);
+ if (returnType != null) {
+ inferredType = substitution == null
+ ? returnType
+ : substitution.substituteType(returnType);
+ } else {
+ if (substitution != null) {
+ calleeType =
+ substitution.substituteType(calleeType.withoutTypeParameters);
+ }
+ inferredType = calleeType.returnType;
+ }
+ assert(
+ !containsFreeFunctionTypeVariables(inferredType),
+ "Inferred return type $inferredType contains free variables."
+ "Inferred function type: $calleeType.");
return inferredType;
}
@@ -2142,8 +2177,8 @@
target, node, node.receiver, arguments);
arguments = replacement.arguments;
}
- DartType inferredType = inferInvocation(typeContext, node.fileOffset,
- functionType, functionType.returnType, arguments,
+ DartType inferredType = inferInvocation(
+ typeContext, node.fileOffset, functionType, arguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
receiverType: receiverType,
isImplicitExtensionMember: target.isExtensionMember);
@@ -2252,8 +2287,8 @@
parent?.replaceChild(expression, error);
return const ExpressionInferenceResult(const DynamicType());
}
- DartType inferredType = inferInvocation(typeContext, fileOffset,
- functionType, functionType.returnType, arguments,
+ DartType inferredType = inferInvocation(
+ typeContext, fileOffset, functionType, arguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
receiverType: receiverType,
isImplicitExtensionMember: target.isExtensionMember);
@@ -2614,7 +2649,8 @@
}
if (expectedType is FunctionType) return true;
if (expectedType == typeSchemaEnvironment.functionLegacyRawType) {
- if (!typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+ if (!typeSchemaEnvironment.isSubtypeOf(
+ actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
return true;
}
}
@@ -2915,10 +2951,10 @@
ExtensionAccessCandidate other) {
if (this.isPlatform == other.isPlatform) {
// Both are platform or not platform.
- bool thisIsSubtype =
- typeSchemaEnvironment.isSubtypeOf(this.onType, other.onType);
- bool thisIsSupertype =
- typeSchemaEnvironment.isSubtypeOf(other.onType, this.onType);
+ bool thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
+ this.onType, other.onType, SubtypeCheckMode.ignoringNullabilities);
+ bool thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
+ other.onType, this.onType, SubtypeCheckMode.ignoringNullabilities);
if (thisIsSubtype && !thisIsSupertype) {
// This is subtype of other and not vice-versa.
return true;
@@ -2927,9 +2963,13 @@
return false;
} else if (thisIsSubtype || thisIsSupertype) {
thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
- this.onTypeInstantiateToBounds, other.onTypeInstantiateToBounds);
+ this.onTypeInstantiateToBounds,
+ other.onTypeInstantiateToBounds,
+ SubtypeCheckMode.ignoringNullabilities);
thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
- other.onTypeInstantiateToBounds, this.onTypeInstantiateToBounds);
+ other.onTypeInstantiateToBounds,
+ this.onTypeInstantiateToBounds,
+ SubtypeCheckMode.ignoringNullabilities);
if (thisIsSubtype && !thisIsSupertype) {
// This is subtype of other and not vice-versa.
return true;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
index f8f0ff5..bb90d9d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
@@ -5,6 +5,8 @@
import 'package:kernel/ast.dart'
show DartType, Expression, TypeParameterType, VariableDeclaration;
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
import '../fasta_codes.dart' show templateInternalProblemStackNotEmpty;
import '../problems.dart' show internalProblem;
@@ -682,16 +684,18 @@
// What we do now depends on the relationship between the previous type of
// the variable and the type we are checking against.
DartType previousType = previousPromotedType ?? variable.type;
- if (promoter.typeSchemaEnvironment.isSubtypeOf(checkedType, previousType)) {
+ if (promoter.typeSchemaEnvironment.isSubtypeOf(
+ checkedType, previousType, SubtypeCheckMode.ignoringNullabilities)) {
// The type we are checking against is a subtype of the previous type of
// the variable, so this is a refinement; we can promote.
return checkedType;
} else if (previousType is TypeParameterType &&
- promoter.typeSchemaEnvironment
- .isSubtypeOf(checkedType, previousType.bound)) {
+ promoter.typeSchemaEnvironment.isSubtypeOf(checkedType,
+ previousType.bound, SubtypeCheckMode.ignoringNullabilities)) {
// The type we are checking against is a subtype of the bound of the
// previous type of the variable; we can promote the bound.
- return new TypeParameterType(previousType.parameter, checkedType);
+ return new TypeParameterType(
+ previousType.parameter, checkedType, previousType.nullability);
} else {
// The types aren't sufficiently related; we can't promote.
return previousPromotedType;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 1634efb..6a2aa4e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -10,6 +10,7 @@
FunctionType,
InterfaceType,
NamedType,
+ Nullability,
TypedefType,
Visitor;
@@ -18,8 +19,6 @@
import 'package:kernel/text/ast_to_text.dart'
show Annotator, NameSystem, Printer, globalDebuggingNames;
-import '../problems.dart' show unsupported;
-
/// Determines whether a type schema contains `?` somewhere inside it.
bool isKnown(DartType schema) => schema.accept(new _IsKnownVisitor());
@@ -60,7 +59,7 @@
/// purely part of the local inference process.
class UnknownType extends DartType {
@override
- get nullability => unsupported("nullability", -1, null);
+ Nullability get nullability => null;
const UnknownType();
@@ -81,6 +80,9 @@
@override
visitChildren(Visitor<dynamic> v) {}
+
+ @override
+ UnknownType withNullability(Nullability nullability) => this;
}
/// Visitor that computes [isKnown].
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 5f8280e..8339567 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
@@ -19,6 +19,8 @@
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
import 'package:kernel/src/hierarchy_based_type_environment.dart'
show HierarchyBasedTypeEnvironment;
@@ -267,7 +269,8 @@
if (success && !hasOmittedBound(typeParam)) {
// If everything else succeeded, check the `extends` constraint.
DartType extendsConstraint = typeParamBound;
- success = isSubtypeOf(inferred, extendsConstraint);
+ success = isSubtypeOf(inferred, extendsConstraint,
+ SubtypeCheckMode.ignoringNullabilities);
}
if (!success) {
@@ -288,10 +291,11 @@
}
@override
- bool isSubtypeOf(DartType subtype, DartType supertype) {
+ bool isSubtypeOf(
+ DartType subtype, DartType supertype, SubtypeCheckMode mode) {
if (subtype is UnknownType) return true;
if (subtype == Null && supertype is UnknownType) return true;
- return super.isSubtypeOf(subtype, supertype);
+ return super.isSubtypeOf(subtype, supertype, mode);
}
bool isEmptyContext(DartType context) {
@@ -359,8 +363,10 @@
/// Determine if the given [type] satisfies the given type [constraint].
bool typeSatisfiesConstraint(DartType type, TypeConstraint constraint) {
- return isSubtypeOf(constraint.lower, type) &&
- isSubtypeOf(type, constraint.upper);
+ return isSubtypeOf(
+ constraint.lower, type, SubtypeCheckMode.ignoringNullabilities) &&
+ isSubtypeOf(
+ type, constraint.upper, SubtypeCheckMode.ignoringNullabilities);
}
DartType _inferTypeParameterFromAll(DartType typeFromContextInference,
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index 0afbb82..a7be604 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -61,9 +61,8 @@
DataExtractor(this.actualMap);
- void computeForLibrary(Library library, {bool useFileUri: false}) {
- LibraryId id =
- new LibraryId(useFileUri ? library.fileUri : library.importUri);
+ void computeForLibrary(Library library) {
+ LibraryId id = new LibraryId(library.fileUri);
T value = computeLibraryValue(id, library);
registerValue(library.fileUri, null, id, value, library);
}
diff --git a/pkg/front_end/lib/src/testing/id_testing.dart b/pkg/front_end/lib/src/testing/id_testing.dart
index 6aba9fb..3c49ea0 100644
--- a/pkg/front_end/lib/src/testing/id_testing.dart
+++ b/pkg/front_end/lib/src/testing/id_testing.dart
@@ -214,6 +214,8 @@
entry;
}
}
+ assert(
+ mainTestFile != null, "No 'main.dart' test file found for $testFile.");
}
String annotatedCode = new File.fromUri(mainTestFile.uri).readAsStringSync();
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index ec92375..68aa64d 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -8,6 +8,7 @@
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
import '../api_prototype/terminal_color_support.dart'
show printDiagnosticMessage;
+import '../base/common.dart';
import '../fasta/messages.dart' show FormattedMessage;
import '../fasta/severity.dart' show Severity;
import '../kernel_generator_impl.dart' show InternalCompilerResult;
@@ -42,8 +43,10 @@
final String marker;
final String name;
final Map<ExperimentalFlag, bool> experimentalFlags;
+ final Uri librariesSpecificationUri;
- const TestConfig(this.marker, this.name, {this.experimentalFlags = const {}});
+ const TestConfig(this.marker, this.name,
+ {this.experimentalFlags = const {}, this.librariesSpecificationUri});
void customizeCompilerOptions(CompilerOptions options) {}
}
@@ -180,6 +183,7 @@
/// Creates a test runner for [dataComputer] on [testedConfigs].
RunTestFunction runTestFor<T>(
DataComputer<T> dataComputer, List<TestConfig> testedConfigs) {
+ retainDataForTesting = true;
return (TestData testData,
{bool testAfterFailures, bool verbose, bool succinct, bool printCode}) {
return runTest(testData, dataComputer, testedConfigs,
@@ -242,6 +246,13 @@
};
options.debugDump = printCode;
options.experimentalFlags.addAll(config.experimentalFlags);
+ if (config.librariesSpecificationUri != null) {
+ Set<Uri> testFiles =
+ testData.memorySourceFiles.keys.map(createUriForFileName).toSet();
+ if (testFiles.contains(config.librariesSpecificationUri)) {
+ options.librariesSpecificationUri = config.librariesSpecificationUri;
+ }
+ }
config.customizeCompilerOptions(options);
InternalCompilerResult compilerResult = await compileScript(
testData.memorySourceFiles,
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index d32d8f5..0c98653 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -62,7 +62,7 @@
(Extension extension) => extension.name == extensionName, orElse: () {
if (required) {
throw new ArgumentError(
- "Extension '$extensionName' not found in '$library'.");
+ "Extension '$extensionName' not found in '${library.importUri}'.");
}
return null;
});
@@ -151,7 +151,7 @@
lookupClassBuilder(compilerResult, cls, required: required);
MemberBuilder memberBuilder;
if (classBuilder != null) {
- if (member is Constructor) {
+ if (member is Constructor || member is Procedure && member.isFactory) {
memberBuilder = classBuilder.constructors.local[memberName];
} else if (member is Procedure && member.isSetter) {
memberBuilder = classBuilder.scope.setters[memberName];
@@ -527,9 +527,6 @@
/// Returns a textual representation of [descriptor] to be used in testing.
String extensionMethodDescriptorToText(ExtensionMemberDescriptor descriptor) {
StringBuffer sb = new StringBuffer();
- if (descriptor.isExternal) {
- sb.write('external ');
- }
if (descriptor.isStatic) {
sb.write('static ');
}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 34bb332..ccc99a2 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -215,6 +215,7 @@
ExtensionDeclaresAbstractMember/example: Fail
ExtensionDeclaresConstructor/example: Fail
ExtensionDeclaresInstanceField/example: Fail
+ExtensionMemberConflictsWithObjectMember/analyzerCode: Fail
ExtraneousModifier/part_wrapped_script1: Fail
ExtraneousModifier/part_wrapped_script2: Fail
ExtraneousModifier/part_wrapped_script3: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 2782772..e67853d 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -457,8 +457,8 @@
EqualityCannotBeEqualityOperand:
index: 1
- template: "An equality expression can't be an operand of another equality expression."
- tip: "Try re-writing the expression."
+ template: "A comparison expression can't be an operand of another comparison expression."
+ tip: "Try putting parentheses around one of the comparisons."
analyzerCode: ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
script:
- "main() { var b = a < b < c; }"
@@ -703,7 +703,7 @@
ExternalField:
index: 50
template: "Fields can't be declared to be 'external'."
- tip: "Try removing the keyword 'external'."
+ tip: "Try removing the keyword 'external', or replacing the field by an external getter and/or setter."
analyzerCode: ParserErrorCode.EXTERNAL_FIELD
script:
- "class C { external var f; }"
@@ -926,7 +926,7 @@
script: "main() sync {}"
InvalidVoid:
- template: "Type 'void' can't be used here because it isn't a return type."
+ template: "Type 'void' can't be used here."
tip: "Try removing 'void' keyword or replace it with 'var', 'final', or a type."
analyzerCode: EXPECTED_TYPE_NAME
script:
@@ -943,7 +943,7 @@
FieldInitializedOutsideDeclaringClass:
index: 88
- template: "A field can only be initialized in it's declaring class"
+ template: "A field can only be initialized in its declaring class"
tip: "Try passing a value into the superclass constructor, or moving the initialization into the constructor body."
analyzerCode: ParserErrorCode.FIELD_INITIALIZED_OUTSIDE_DECLARING_CLASS
script:
@@ -1137,7 +1137,6 @@
BuiltInIdentifierAsType:
template: "The built-in identifier '#lexeme' can't be used as a type."
- tip: "Try correcting the name to match an existing type."
analyzerCode: BUILT_IN_IDENTIFIER_AS_TYPE
BuiltInIdentifierInDeclaration:
@@ -1265,12 +1264,12 @@
ConstFieldWithoutInitializer:
template: "The const variable '#name' must be initialized."
- tip: "Try adding an initializer ('= <expression>') to the declaration."
+ tip: "Try adding an initializer ('= expression') to the declaration."
analyzerCode: CONST_NOT_INITIALIZED
FinalFieldWithoutInitializer:
template: "The final variable '#name' must be initialized."
- tip: "Try adding an initializer ('= <expression>') to the declaration."
+ tip: "Try adding an initializer ('= expression') to the declaration."
analyzerCode: FINAL_NOT_INITIALIZED
MetadataTypeArguments:
@@ -1718,7 +1717,7 @@
MissingPrefixInDeferredImport:
index: 30
template: "Deferred imports should have a prefix."
- tip: "Try adding a prefix to the import."
+ tip: "Try adding a prefix to the import by adding an 'as' clause."
analyzerCode: ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT
DeferredAfterPrefix:
@@ -1936,6 +1935,13 @@
template: "This is the type variable."
severity: CONTEXT
+ExtensionMemberConflictsWithObjectMember:
+ template: "This extension member conflicts with Object member '#name'."
+ script:
+ extension Extension on String {
+ int get noSuchMethod => 42;
+ }
+
DeclaredMemberConflictsWithInheritedMember:
template: "Can't declare a member that conflicts with an inherited one."
analyzerCode: DECLARED_MEMBER_CONFLICTS_WITH_INHERITED
@@ -2781,7 +2787,7 @@
MissingAssignableSelector:
index: 35
- template: "Missing selector such as '.<identifier>' or '[0]'."
+ template: "Missing selector such as '.identifier' or '[0]'."
tip: "Try adding a selector."
analyzerCode: ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR
script:
@@ -2833,12 +2839,10 @@
ArgumentTypeNotAssignable:
template: "The argument type '#type' can't be assigned to the parameter type '#type2'."
- tip: "Try changing the type of the parameter, or casting the argument to '#type2'."
analyzerCode: ARGUMENT_TYPE_NOT_ASSIGNABLE
InvalidAssignment:
template: "A value of type '#type' can't be assigned to a variable of type '#type2'."
- tip: "Try changing the type of the left hand side, or casting the right hand side to '#type2'."
analyzerCode: INVALID_ASSIGNMENT
script: >
main() {
@@ -3157,7 +3161,7 @@
CantUsePrefixWithNullAware:
template: "A prefix can't be used with null-aware operators."
- tip: "It should be safe to remove the '?' as a prefix is never null."
+ tip: "Try replacing '?.' with '.'"
analyzerCode: PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
script: |
import "dart:core" as prefix;
@@ -3418,7 +3422,7 @@
class C = Object with M;
GenericFunctionTypeUsedAsActualTypeArgument:
- template: "Unexpected generic function type found in a type argument."
+ template: "A generic function type can't be used as a type argument."
tip: "Try using a non-generic function type."
analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
script:
@@ -3434,7 +3438,7 @@
}
GenericFunctionTypeInferredAsActualTypeArgument:
- template: "Unexpected generic function type '#type' inferred as a type argument."
+ template: "Generic function type '#type' inferred as a type argument."
tip: "Try providing a non-generic function type explicitly."
analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
script:
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
new file mode 100644
index 0000000..7bf2cde
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
@@ -0,0 +1,88 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, foo)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(baz, expressionContinuation)
+ listener: handleNoTypeArguments([)
+ parseArgumentsOpt(baz)
+ listener: handleNoArguments([)
+ listener: handleSend(baz, [)
+ listener: endBinaryExpression(.)
+ parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..69fcc2c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,99 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments())
+ listener: handleSend(bar, ))
+ listener: endBinaryExpression(.)
+ ensureCloseParen(bar, ()
+ listener: handleParenthesizedExpression(()
+ listener: handleNonNullAssertExpression(!)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(baz, expressionContinuation)
+ listener: handleNoTypeArguments([)
+ parseArgumentsOpt(baz)
+ listener: handleNoArguments([)
+ listener: handleSend(baz, [)
+ listener: endBinaryExpression(.)
+ parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
new file mode 100644
index 0000000..109f304
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
@@ -0,0 +1,68 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, obj)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(obj)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(obj, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(obj)
+ listener: handleNoArguments(!)
+ listener: handleSend(obj, !)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
new file mode 100644
index 0000000..0b43b40
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
@@ -0,0 +1,83 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, obj)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(obj)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(obj, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(obj)
+ listener: handleNoArguments(!)
+ listener: handleSend(obj, !)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..6c15e07
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
@@ -0,0 +1,114 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(obj, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(obj)
+ listener: handleNoArguments(!)
+ listener: handleSend(obj, !)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureCloseParen(], ()
+ listener: handleParenthesizedExpression(()
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
new file mode 100644
index 0000000..f3b48e4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
@@ -0,0 +1,78 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, foo)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..c349f09
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
@@ -0,0 +1,89 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments())
+ listener: handleSend(bar, ))
+ listener: endBinaryExpression(.)
+ ensureCloseParen(bar, ()
+ listener: handleParenthesizedExpression(()
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
new file mode 100644
index 0000000..89095e5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, foo)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(!)
+ listener: handleSend(foo, !)
+ listener: handleNonNullAssertExpression(!)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..4e8d872
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
@@ -0,0 +1,100 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(!)
+ listener: handleSend(foo, !)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
new file mode 100644
index 0000000..c6b3abd
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
@@ -0,0 +1,93 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, foo)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..1f1f0bf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
@@ -0,0 +1,124 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(.)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(.)
+ listener: handleSend(foo, .)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureCloseParen(], ()
+ listener: handleParenthesizedExpression(()
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
new file mode 100644
index 0000000..795f82d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
@@ -0,0 +1,94 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, foo)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(!)
+ listener: handleSend(foo, !)
+ listener: handleNonNullAssertExpression(!)
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ listener: handleNonNullAssertExpression(!)
+ parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..41a6cb6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
@@ -0,0 +1,135 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseParenthesizedExpressionOrFunctionLiteral(()
+ parseParenthesizedExpression(()
+ parseExpressionInParenthesis(()
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments(!)
+ listener: handleSend(foo, !)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parsePrimary(., expressionContinuation)
+ parseSendOrFunctionLiteral(., expressionContinuation)
+ parseSend(., expressionContinuation)
+ ensureIdentifier(., expressionContinuation)
+ listener: handleIdentifier(bar, expressionContinuation)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(bar)
+ listener: handleNoArguments(!)
+ listener: handleSend(bar, !)
+ listener: endBinaryExpression(.)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureCloseParen(], ()
+ listener: handleParenthesizedExpression(()
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg2, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg2)
+ listener: handleNoArguments(])
+ listener: handleSend(arg2, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..0f8729a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+ listener: beginTopLevelMethod(, null)
+ listener: handleNoType()
+ ensureIdentifier(, topLevelFunctionDeclaration)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, ()
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclaration({, false)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(()
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseParenthesizedExpressionOrFunctionLiteral({)
+ parseParenthesizedExpression({)
+ parseExpressionInParenthesis({)
+ parseExpressionInParenthesisRest(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(obj, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(obj)
+ listener: handleNoArguments(!)
+ listener: handleSend(obj, !)
+ listener: handleNonNullAssertExpression(!)
+ ensureCloseParen(!, ()
+ listener: handleParenthesizedExpression(()
+ parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+ parseExpression([)
+ parsePrecedenceExpression([, 1, true)
+ parseUnaryExpression([, true)
+ parsePrimary([, expression)
+ parseSendOrFunctionLiteral([, expression)
+ parseSend([, expression)
+ ensureIdentifier([, expression)
+ listener: handleIdentifier(arg, expression)
+ listener: handleNoTypeArguments(])
+ parseArgumentsOpt(arg)
+ listener: handleNoArguments(])
+ listener: handleSend(arg, ])
+ listener: handleIndexedExpression([, ])
+ ensureSemicolon(])
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/test/extensions/data/as_show/lib.dart b/pkg/front_end/test/extensions/data/as_show/lib.dart
new file mode 100644
index 0000000..e89ef0c
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/lib.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.
+
+/*library: scope=[Extension1]*/
+
+/*class: Extension1:
+ builder-name=Extension1,
+ builder-onType=String,
+ extension-members=[
+ method1=Extension1|method1,
+ tearoff method1=Extension1|get#method1],
+ extension-name=Extension1,
+ extension-onType=String
+*/
+extension Extension1 on String {
+ /*member: Extension1|method1:
+ builder-name=method1,
+ builder-params=[#this],
+ member-name=Extension1|method1,
+ member-params=[#this]
+ */
+ method1() {}
+
+ /*member: Extension1|get#method1:
+ builder-name=method1,
+ builder-params=[#this],
+ member-name=Extension1|get#method1,
+ member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/as_show/libraries.json b/pkg/front_end/test/extensions/data/as_show/libraries.json
new file mode 100644
index 0000000..7a584cb
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/libraries.json
@@ -0,0 +1,9 @@
+{
+ "none": {
+ "libraries": {
+ "test": {
+ "uri": "origin.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/main.dart b/pkg/front_end/test/extensions/data/as_show/main.dart
new file mode 100644
index 0000000..2a7d2d1
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/main.dart
@@ -0,0 +1,20 @@
+// 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: scope=[lib.dart.Extension1,origin.dart.Extension2]*/
+
+import 'lib.dart' as lib1;
+import 'lib.dart' show Extension1;
+
+// ignore: uri_does_not_exist
+import 'dart:test' as lib2;
+// ignore: uri_does_not_exist
+import 'dart:test' show Extension2;
+
+main() {
+ "".method1();
+ Extension1("").method1();
+ "".method2();
+ Extension2("").method2();
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/origin.dart b/pkg/front_end/test/extensions/data/as_show/origin.dart
new file mode 100644
index 0000000..1b36bb9
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/origin.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.
+
+/*library: scope=[Extension2]*/
+
+/*class: Extension2:
+ builder-name=Extension2,
+ builder-onType=String,
+ extension-members=[
+ method2=Extension2|method2,
+ tearoff method2=Extension2|get#method2],
+ extension-name=Extension2,
+ extension-onType=String
+*/
+extension Extension2 on String {
+/*member: Extension2|method2:
+ builder-name=method2,
+ builder-params=[#this],
+ member-name=Extension2|method2,
+ member-params=[#this]
+ */
+method2() {}
+
+/*member: Extension2|get#method2:
+ builder-name=method2,
+ builder-params=[#this],
+ member-name=Extension2|get#method2,
+ member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/libraries.json b/pkg/front_end/test/extensions/data/patching/libraries.json
new file mode 100644
index 0000000..a697508
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/libraries.json
@@ -0,0 +1,12 @@
+{
+ "none": {
+ "libraries": {
+ "test": {
+ "patches": [
+ "patch.dart"
+ ],
+ "uri": "origin.dart"
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/test/extensions/data/patching/main.dart b/pkg/front_end/test/extensions/data/patching/main.dart
new file mode 100644
index 0000000..9599059
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/main.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.
+
+/*library: scope=[origin.dart.Extension,origin.dart.GenericExtension]*/
+
+// ignore: uri_does_not_exist
+import 'dart:test';
+
+main() {
+ "".instanceMethod();
+ "".genericInstanceMethod<int>(0);
+ "".instanceProperty = "".instanceProperty;
+ Extension.staticMethod();
+ Extension.genericStaticMethod<int>(0);
+ Extension.staticProperty = Extension.staticProperty;
+ true.instanceMethod();
+ true.genericInstanceMethod<int>(0);
+ true.instanceProperty = true.instanceProperty;
+ GenericExtension.staticMethod();
+ GenericExtension.genericStaticMethod<int>(0);
+ GenericExtension.staticProperty = GenericExtension.staticProperty;
+}
diff --git a/pkg/front_end/test/extensions/data/patching/origin.dart b/pkg/front_end/test/extensions/data/patching/origin.dart
new file mode 100644
index 0000000..1a5b69e
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/origin.dart
@@ -0,0 +1,108 @@
+// 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: scope=[Extension,GenericExtension]*/
+
+/*class: Extension:
+ builder-name=Extension,
+ builder-onType=String,
+ extension-members=[
+ genericInstanceMethod=Extension|genericInstanceMethod,
+ getter instanceProperty=Extension|get#instanceProperty,
+ instanceMethod=Extension|instanceMethod,
+ setter instanceProperty=Extension|set#instanceProperty,
+ static genericStaticMethod=Extension|genericStaticMethod,
+ static getter staticProperty=Extension|staticProperty,
+ static setter staticProperty=Extension|staticProperty=,
+ static staticMethod=Extension|staticMethod,
+ tearoff genericInstanceMethod=Extension|get#genericInstanceMethod,
+ tearoff instanceMethod=Extension|get#instanceMethod,
+ ],
+ extension-name=Extension,
+ extension-onType=String
+*/
+extension Extension on String {
+ /*member: Extension|get#instanceMethod:
+ builder-name=instanceMethod,
+ builder-params=[#this],
+ member-name=Extension|get#instanceMethod,
+ member-params=[#this]
+ */
+ external int instanceMethod();
+
+ /*member: Extension|get#genericInstanceMethod:
+ builder-name=genericInstanceMethod,
+ builder-params=[#this,t],
+ builder-type-params=[T],
+ member-name=Extension|get#genericInstanceMethod,
+ member-params=[#this]
+ */
+ external T genericInstanceMethod<T>(T t);
+
+ external static int staticMethod();
+
+ external static T genericStaticMethod<T>(T t);
+
+ external int get instanceProperty;
+
+ external void set instanceProperty(int value);
+
+ external static int get staticProperty;
+
+ external static void set staticProperty(int value);
+}
+
+/*class: GenericExtension:
+ builder-name=GenericExtension,
+ builder-onType=T,
+ builder-type-params=[T],
+ extension-members=[
+ genericInstanceMethod=GenericExtension|genericInstanceMethod,
+ getter instanceProperty=GenericExtension|get#instanceProperty,
+ instanceMethod=GenericExtension|instanceMethod,
+ setter instanceProperty=GenericExtension|set#instanceProperty,
+ static genericStaticMethod=GenericExtension|genericStaticMethod,
+ static getter staticProperty=GenericExtension|staticProperty,
+ static setter staticProperty=GenericExtension|staticProperty=,
+ static staticMethod=GenericExtension|staticMethod,
+ tearoff genericInstanceMethod=GenericExtension|get#genericInstanceMethod,
+ tearoff instanceMethod=GenericExtension|get#instanceMethod
+ ],
+ extension-name=GenericExtension,
+ extension-onType=T,
+ extension-type-params=[T]
+*/
+extension GenericExtension<T> on T {
+ /*member: GenericExtension|get#instanceMethod:
+ builder-name=instanceMethod,
+ builder-params=[#this],
+ builder-type-params=[T],
+ member-name=GenericExtension|get#instanceMethod,
+ member-params=[#this],
+ member-type-params=[T]
+ */
+ external int instanceMethod();
+
+ /*member: GenericExtension|get#genericInstanceMethod:
+ builder-name=genericInstanceMethod,
+ builder-params=[#this,t],
+ builder-type-params=[T,T],
+ member-name=GenericExtension|get#genericInstanceMethod,
+ member-params=[#this],
+ member-type-params=[#T]
+ */
+ external T genericInstanceMethod<T>(T t);
+
+ external static int staticMethod();
+
+ external static T genericStaticMethod<T>(T t);
+
+ external int get instanceProperty;
+
+ external void set instanceProperty(int value);
+
+ external static int get staticProperty;
+
+ external static void set staticProperty(int value);
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/patch.dart b/pkg/front_end/test/extensions/data/patching/patch.dart
new file mode 100644
index 0000000..32edfc4
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/patch.dart
@@ -0,0 +1,163 @@
+// 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.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+extension Extension on String {
+ /*member: Extension|instanceMethod:
+ builder-name=instanceMethod,
+ builder-params=[#this],
+ member-name=Extension|instanceMethod,
+ member-params=[#this]
+ */
+ @patch
+ int instanceMethod() => 42;
+
+ /*member: Extension|genericInstanceMethod:
+ builder-name=genericInstanceMethod,
+ builder-params=[#this,t],
+ builder-type-params=[T],
+ member-name=Extension|genericInstanceMethod,
+ member-params=[#this,t],
+ member-type-params=[T]
+ */
+ @patch
+ T genericInstanceMethod<T>(T t) => t;
+
+ /*member: Extension|staticMethod:
+ builder-name=staticMethod,
+ member-name=Extension|staticMethod
+ */
+ @patch
+ static int staticMethod() => 87;
+
+ /*member: Extension|genericStaticMethod:
+ builder-name=genericStaticMethod,
+ builder-params=[t],
+ builder-type-params=[T],
+ member-name=Extension|genericStaticMethod,
+ member-params=[t],
+ member-type-params=[T]
+ */
+ @patch
+ static T genericStaticMethod<T>(T t) => t;
+
+ /*member: Extension|get#instanceProperty:
+ builder-name=instanceProperty,
+ builder-params=[#this],
+ member-name=Extension|get#instanceProperty,
+ member-params=[#this]
+ */
+ @patch
+ int get instanceProperty => 123;
+
+ /*member: Extension|set#instanceProperty:
+ builder-name=instanceProperty,
+ builder-params=[#this,value],
+ member-name=Extension|set#instanceProperty,
+ member-params=[#this,value]
+ */
+ @patch
+ void set instanceProperty(int value) {}
+
+ /*member: Extension|staticProperty:
+ builder-name=staticProperty,
+ member-name=Extension|staticProperty
+ */
+ @patch
+ static int get staticProperty => 237;
+
+ /*member: Extension|staticProperty=:
+ builder-name=staticProperty,
+ builder-params=[value],
+ member-name=Extension|staticProperty=,
+ member-params=[value]
+ */
+ @patch
+ static void set staticProperty(int value) {}
+}
+
+
+@patch
+extension GenericExtension<T> on T {
+ /*member: GenericExtension|instanceMethod:
+ builder-name=instanceMethod,
+ builder-params=[#this],
+ builder-type-params=[T],
+ member-name=GenericExtension|instanceMethod,
+ member-params=[#this],
+ member-type-params=[T]
+ */
+ @patch
+ int instanceMethod() => 42;
+
+ /*member: GenericExtension|genericInstanceMethod:
+ builder-name=genericInstanceMethod,
+ builder-params=[#this,t],
+ builder-type-params=[T,T],
+ member-name=GenericExtension|genericInstanceMethod,
+ member-params=[#this,t],
+ member-type-params=[#T,T]
+ */
+ @patch
+ T genericInstanceMethod<T>(T t) => t;
+
+ /*member: GenericExtension|staticMethod:
+ builder-name=staticMethod,
+ member-name=GenericExtension|staticMethod
+ */
+ @patch
+ static int staticMethod() => 87;
+
+ /*member: GenericExtension|genericStaticMethod:
+ builder-name=genericStaticMethod,
+ builder-params=[t],
+ builder-type-params=[T],
+ member-name=GenericExtension|genericStaticMethod,
+ member-params=[t],
+ member-type-params=[T]
+ */
+ @patch
+ static T genericStaticMethod<T>(T t) => t;
+
+ /*member: GenericExtension|get#instanceProperty:
+ builder-name=instanceProperty,
+ builder-params=[#this],
+ builder-type-params=[T],
+ member-name=GenericExtension|get#instanceProperty,
+ member-params=[#this],
+ member-type-params=[T]
+ */
+ @patch
+ int get instanceProperty => 123;
+
+ /*member: GenericExtension|set#instanceProperty:
+ builder-name=instanceProperty,
+ builder-params=[#this,value],
+ builder-type-params=[T],
+ member-name=GenericExtension|set#instanceProperty,
+ member-params=[#this,value],
+ member-type-params=[T]
+ */
+ @patch
+ void set instanceProperty(int value) {}
+
+ /*member: GenericExtension|staticProperty:
+ builder-name=staticProperty,
+ member-name=GenericExtension|staticProperty
+ */
+ @patch
+ static int get staticProperty => 237;
+
+ /*member: GenericExtension|staticProperty=:
+ builder-name=staticProperty,
+ builder-params=[value],
+ member-name=GenericExtension|staticProperty=,
+ member-params=[value]
+ */
+ @patch
+ static void set staticProperty(int value) {}
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 33e8fb4..880d249 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io' show Directory, Platform;
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+ show ExperimentalFlag;
import 'package:front_end/src/fasta/builder/builder.dart';
import 'package:front_end/src/fasta/builder/extension_builder.dart';
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
@@ -22,8 +24,11 @@
supportedMarkers: sharedMarkers,
createUriForFileName: createUriForFileName,
onFailure: onFailure,
- runTest: runTestFor(
- const ExtensionsDataComputer(), [cfeExtensionMethodsConfig]));
+ runTest: runTestFor(const ExtensionsDataComputer(), [
+ new TestConfig(cfeMarker, 'cfe with extension methods',
+ experimentalFlags: const {ExperimentalFlag.extensionMethods: true},
+ librariesSpecificationUri: createUriForFileName('libraries.json'))
+ ]));
}
class ExtensionsDataComputer extends DataComputer<Features> {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 1908a65..c92c98e 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -8,6 +8,7 @@
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/type_environment.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -691,13 +692,17 @@
void test_unknown_at_bottom() {
var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
- expect(env.isSubtypeOf(unknownType, A), isTrue);
+ expect(
+ env.isSubtypeOf(unknownType, A, SubtypeCheckMode.ignoringNullabilities),
+ isTrue);
}
void test_unknown_at_top() {
var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
- expect(env.isSubtypeOf(A, unknownType), isTrue);
+ expect(
+ env.isSubtypeOf(A, unknownType, SubtypeCheckMode.ignoringNullabilities),
+ isTrue);
}
Class _addClass(Class c) {
diff --git a/pkg/front_end/test/fasta/types/fasta_types_test.dart b/pkg/front_end/test/fasta/types/fasta_types_test.dart
index f4dc886..5d3659a 100644
--- a/pkg/front_end/test/fasta/types/fasta_types_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_types_test.dart
@@ -26,6 +26,7 @@
show ClassHierarchyBuilder, ClassBuilder;
import "package:front_end/src/fasta/ticker.dart" show Ticker;
+import 'package:kernel/type_environment.dart';
import "kernel_type_parser.dart" show KernelEnvironment, KernelFromParsedType;
@@ -73,7 +74,8 @@
}
bool isSubtypeImpl(DartType subtype, DartType supertype) {
- return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+ return hierarchy.types.isSubtypeOfKernel(
+ subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
}
KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
index c8af98e..d03b95d 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
@@ -12,7 +12,8 @@
import "package:kernel/text/ast_to_text.dart" show Printer;
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+ show SubtypeCheckMode, TypeEnvironment;
import "kernel_type_parser.dart"
show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -42,7 +43,7 @@
typedef Typedef<T extends self::Object* = dynamic> = <S extends self::Object* = dynamic>(T*) →* S*;
typedef VoidFunction = () →* void;
-typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>*, self::List<self::Object>*, self::Comparable<dynamic>*, (<BottomType>) →* void, () →* self::Comparable<dynamic>*>;
+typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>, self::List<self::Object>, self::Comparable<dynamic>, (<BottomType>) → void, () → self::Comparable<dynamic>>;
typedef Id<T extends self::Object* = dynamic> = T*;
typedef TestSorting = ({a: self::int, b: self::int, c: self::int}) →* void;
class Object {
@@ -71,13 +72,13 @@
}
class bool extends self::Object {
}
-class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>*, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>*, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>*, X extends (self::DefaultTypes::W) → void = (<BottomType>) →* void, Y extends () → self::DefaultTypes::W = () →* self::Comparable<dynamic>*> extends self::Object {
+class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>, X extends (self::DefaultTypes::W) → void = (<BottomType>) → void, Y extends () → self::DefaultTypes::W = () → self::Comparable<dynamic>> extends self::Object {
}
class Super extends self::Object implements self::Comparable<self::Sub> {
}
class Sub extends self::Super {
}
-class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>*> extends self::Object {
+class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>> extends self::Object {
}
class MixinApplication = self::Object with self::FBound<self::MixinApplication> {
}
@@ -119,8 +120,8 @@
}
bool isSubtypeImpl(DartType subtype, DartType supertype) {
- return new TypeEnvironment(coreTypes, hierarchy)
- .isSubtypeOf(subtype, supertype);
+ return new TypeEnvironment(coreTypes, hierarchy).isSubtypeOf(
+ subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
}
KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
index dc3e3f8..c46d75a 100644
--- a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
+++ b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
@@ -14,7 +14,8 @@
import "package:kernel/target/targets.dart" show NoneTarget, TargetFlags;
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+ show SubtypeCheckMode, TypeEnvironment;
import "kernel_type_parser.dart"
show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -101,7 +102,8 @@
void performChecks(List<SubtypeCheck> checks, TypeEnvironment environment) {
for (int i = 0; i < checks.length; i++) {
SubtypeCheck check = checks[i];
- bool isSubtype = environment.isSubtypeOf(check.s, check.t);
+ bool isSubtype = environment.isSubtypeOf(
+ check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
if (isSubtype != check.isSubtype) {
throw "Check failed: $check";
}
@@ -112,7 +114,8 @@
List<SubtypeCheck> checks, ClassHierarchyBuilder hierarchy) {
for (int i = 0; i < checks.length; i++) {
SubtypeCheck check = checks[i];
- bool isSubtype = hierarchy.types.isSubtypeOfKernel(check.s, check.t);
+ bool isSubtype = hierarchy.types.isSubtypeOfKernel(
+ check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
if (isSubtype != check.isSubtype) {
throw "Check failed: $check";
}
diff --git a/pkg/front_end/test/id_testing/id_testing_test.dart b/pkg/front_end/test/id_testing/id_testing_test.dart
index 07d99ba..92a4fb5 100644
--- a/pkg/front_end/test/id_testing/id_testing_test.dart
+++ b/pkg/front_end/test/id_testing/id_testing_test.dart
@@ -58,7 +58,7 @@
Library library, Map<Id, ActualData<String>> actualMap,
{bool verbose}) {
new IdTestingDataExtractor(compilerResult, actualMap)
- .computeForLibrary(library, useFileUri: true);
+ .computeForLibrary(library);
}
@override
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart
index 691df94..a387f9a 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -52,7 +52,7 @@
Library library, Map<Id, ActualData<String>> actualMap,
{bool verbose}) {
new LanguageVersioningDataExtractor(compilerResult, actualMap)
- .computeForLibrary(library, useFileUri: true);
+ .computeForLibrary(library);
}
@override
diff --git a/pkg/front_end/test/parser_test.dart b/pkg/front_end/test/parser_test.dart
index 3c6cffb..9daee4d 100644
--- a/pkg/front_end/test/parser_test.dart
+++ b/pkg/front_end/test/parser_test.dart
@@ -31,6 +31,8 @@
import 'parser_test_listener.dart' show ParserTestListener;
+import 'parser_test_parser.dart' show TestParser;
+
const String EXPECTATIONS = '''
[
{
@@ -58,17 +60,18 @@
Context(this.updateExpectations);
final List<Step> steps = const <Step>[
- const ParserStep(),
+ const ListenerStep(),
+ const IntertwinedStep(),
];
final ExpectationSet expectationSet =
new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
}
-class ParserStep extends Step<TestDescription, TestDescription, Context> {
- const ParserStep();
+class ListenerStep extends Step<TestDescription, TestDescription, Context> {
+ const ListenerStep();
- String get name => "parser";
+ String get name => "listener";
Future<Result<TestDescription>> run(
TestDescription description, Context context) async {
@@ -94,3 +97,43 @@
".expect", "${parserTestListener.sb}", description.uri, description);
}
}
+
+class IntertwinedStep extends Step<TestDescription, TestDescription, Context> {
+ const IntertwinedStep();
+
+ String get name => "intertwined";
+
+ Future<Result<TestDescription>> run(
+ TestDescription description, Context context) async {
+ File f = new File.fromUri(description.uri);
+ List<int> rawBytes = f.readAsBytesSync();
+
+ Uint8List bytes = new Uint8List(rawBytes.length + 1);
+ bytes.setRange(0, rawBytes.length, rawBytes);
+
+ Utf8BytesScanner scanner =
+ new Utf8BytesScanner(bytes, includeComments: true);
+ Token firstToken = scanner.tokenize();
+
+ if (firstToken == null) {
+ return crash(description, StackTrace.current);
+ }
+
+ ParserTestListener2 parserTestListener = new ParserTestListener2();
+ TestParser parser = new TestParser(parserTestListener);
+ parserTestListener.parser = parser;
+ parser.sb = parserTestListener.sb;
+ parser.parseUnit(firstToken);
+
+ return context.match<TestDescription>(
+ ".intertwined.expect", "${parser.sb}", description.uri, description);
+ }
+}
+
+class ParserTestListener2 extends ParserTestListener {
+ TestParser parser;
+
+ void doPrint(String s) {
+ sb.writeln((" " * parser.indent) + "listener: " + s);
+ }
+}
diff --git a/pkg/front_end/test/parser_test_listener_creator.dart b/pkg/front_end/test/parser_test_listener_creator.dart
index 1d625bf..35851e7 100644
--- a/pkg/front_end/test/parser_test_listener_creator.dart
+++ b/pkg/front_end/test/parser_test_listener_creator.dart
@@ -11,8 +11,17 @@
import 'package:front_end/src/fasta/parser/member_kind.dart';
import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
import 'package:front_end/src/scanner/token.dart';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
-main() {
+StringSink out;
+
+main(List<String> args) {
+ if (args.contains("--stdout")) {
+ out = stdout;
+ } else {
+ out = new StringBuffer();
+ }
+
File f = new File.fromUri(
Platform.script.resolve("../lib/src/fasta/parser/listener.dart"));
List<int> rawBytes = f.readAsBytesSync();
@@ -23,7 +32,7 @@
Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
Token firstToken = scanner.tokenize();
- print("""
+ out.write("""
// 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.
@@ -47,15 +56,17 @@
void doPrint(String s) {
sb.writeln((" " * indent) + s);
}
- """);
+""");
ParserCreatorListener listener = new ParserCreatorListener();
ClassMemberParser parser = new ClassMemberParser(listener);
parser.parseUnit(firstToken);
- print("""
+ out.writeln("}");
+
+ if (out is StringBuffer) {
+ stdout.write(new DartFormatter().format("$out"));
}
- """);
}
class ParserCreatorListener extends Listener {
@@ -79,13 +90,14 @@
void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
Token beginInitializers, Token endToken) {
if (insideListenerClass) {
+ out.write(" ");
Token token = beginToken;
Token latestToken;
while (true) {
if (latestToken != null && latestToken.charEnd < token.charOffset) {
- stdout.write(" ");
+ out.write(" ");
}
- stdout.write(token.lexeme);
+ out.write(token.lexeme);
if ((token is BeginToken &&
token.type == TokenType.OPEN_CURLY_BRACKET) ||
token is SimpleToken && token.type == TokenType.FUNCTION) {
@@ -99,29 +111,29 @@
}
if (token is SimpleToken && token.type == TokenType.FUNCTION) {
- stdout.write(" null;");
+ out.write(" null;");
} else {
- stdout.write("\n");
+ out.write("\n ");
if (currentMethodName.startsWith("end")) {
- stdout.write("indent--;\n");
+ out.write("indent--;\n ");
}
- stdout.write("doPrint('$currentMethodName(");
+ out.write("doPrint('$currentMethodName(");
String separator = "";
for (int i = 0; i < parameters.length; i++) {
- stdout.write(separator);
- stdout.write(r"''$");
- stdout.write(parameters[i]);
+ out.write(separator);
+ out.write(r"' '$");
+ out.write(parameters[i]);
separator = ", ";
}
- stdout.write(")');\n");
+ out.write(")');\n ");
if (currentMethodName.startsWith("begin")) {
- stdout.write("indent++;\n");
+ out.write(" indent++;\n ");
}
- stdout.write("}");
+ out.write("}");
}
- stdout.write("\n\n");
+ out.write("\n\n");
}
parameters.clear();
currentMethodName = null;