Version 2.9.0-12.0.dev
Merge commit '3c6a3fba304c1ad03a41d5a25f0b9628451b97de' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 119220f..f698d6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -61,9 +61,15 @@
#### Linter
-Updated the Linter to `0.1.115`, which includes:
+Updated the Linter to `0.1.116`, which includes:
-* Updated `avoid_types_as_parameter_names` to check catch-clauses.
+* New lint: `no_default_cases` (experimental).
+* New lint: `exhaustive_cases`.
+* Updated `type_annotate_public_apis` to allow inferred types in final field assignments.
+* Updated `prefer_mixin` to allow "legacy" SDK abstract class mixins.
+* New lint: `use_is_even_rather_than_modulo`.
+* Updated `unsafe_html` to use a `SecurityLintCode` (making it un-ignorable).
+* Improved `sized_box_for_whitespace` to address false-positives.
* Fixed `unsafe_html` to check attributes and methods on extensions.
* Extended `unsafe_html` to include `Window.open`, `Element.html` and
`DocumentFragment.html` in unsafe API checks.
@@ -86,6 +92,18 @@
column will be empty.
* `pub upgrade`: Show summary count of outdated packages after running.
+## 2.8.3 - 2020-05-28
+
+This is a patch release that fixes the following issues:
+* crashes in Flutter apps (issue [flutter/flutter#57318][]).
+* a regression in stack traces (issue [#41907][]).
+* re-canonicalization of constants with unboxed fields (issue
+[flutter/flutter#57190][]).
+
+[flutter/flutter#57318]: https://github.com/flutter/flutter/issues/57318
+[#41907]: https://github.com/dart-lang/sdk/issues/41907
+[flutter/flutter#57190]: https://github.com/flutter/flutter/issues/57190
+
## 2.8.2 - 2020-05-13
This is a patch release that fixes an AOT compilation bug in global
diff --git a/DEPS b/DEPS
index 9ce14c9..11bf21b 100644
--- a/DEPS
+++ b/DEPS
@@ -106,7 +106,7 @@
"intl_tag": "0.16.1",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "d589e635d8ccb7cda6a804bd571f88abbabab146",
- "linter_tag": "0.1.115",
+ "linter_tag": "0.1.116",
"logging_tag": "9561ba016ae607747ae69b846c0e10958ca58ed4",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_tag": "dd150bb64c5f3b41d31f20f399ae2a855f7f8c00",
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 31de7c2..9472270 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -8793,6 +8793,16 @@
r"""Try removing the keyword 'var', or replacing it with the name of the return type.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeVerificationErrorOriginContext =
+ messageVerificationErrorOriginContext;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageVerificationErrorOriginContext = const MessageCode(
+ "VerificationErrorOriginContext",
+ severity: Severity.context,
+ message: r"""The node most likely is taken from here by a transformer.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeVoidExpression = messageVoidExpression;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 916bcf7..59caf69 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -106,18 +106,7 @@
return ElementKind.MIXIN;
}
}
- if (element is engine.FieldElement &&
- element.isEnumConstant &&
- // MyEnum.values and MyEnum.one.index return isEnumConstant = true
- // so these additional checks are necessary.
- // TODO(danrubel) MyEnum.values is constant, but is a list
- // so should it return isEnumConstant = true?
- // MyEnum.one.index is final but *not* constant
- // so should it return isEnumConstant = true?
- // Or should we return ElementKind.ENUM_CONSTANT here
- // in either or both of these cases?
- element.type != null &&
- element.type.element == element.enclosingElement) {
+ if (element is engine.FieldElement && element.isEnumConstant) {
return ElementKind.ENUM_CONSTANT;
}
return convertElementKind(element.kind);
@@ -187,7 +176,6 @@
}
bool _isAbstract(engine.Element element) {
- // TODO(scheglov) add isAbstract to Element API
if (element is engine.ClassElement) {
return element.isAbstract;
}
@@ -201,7 +189,6 @@
}
bool _isConst(engine.Element element) {
- // TODO(scheglov) add isConst to Element API
if (element is engine.ConstructorElement) {
return element.isConst;
}
@@ -212,7 +199,6 @@
}
bool _isFinal(engine.Element element) {
- // TODO(scheglov) add isFinal to Element API
if (element is engine.VariableElement) {
return element.isFinal;
}
@@ -220,7 +206,6 @@
}
bool _isStatic(engine.Element element) {
- // TODO(scheglov) add isStatic to Element API
if (element is engine.ExecutableElement) {
return element.isStatic;
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6032b6a..4cd286b 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -824,7 +824,6 @@
@override
ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
String defaultPackageFilePath;
- String defaultPackagesDirectoryPath;
var path = (analysisServer.contextManager as ContextManagerImpl)
.normalizedPackageRoots[folder.path];
if (path != null) {
@@ -832,8 +831,6 @@
if (resource.exists) {
if (resource is File) {
defaultPackageFilePath = path;
- } else {
- defaultPackagesDirectoryPath = path;
}
}
}
@@ -841,7 +838,6 @@
var builderOptions = ContextBuilderOptions();
builderOptions.defaultOptions = options;
builderOptions.defaultPackageFilePath = defaultPackageFilePath;
- builderOptions.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
var builder = ContextBuilder(
resourceProvider, analysisServer.sdkManager, null,
options: builderOptions);
@@ -856,7 +852,7 @@
void removeContext(Folder folder, List<String> flushedFiles) {
sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
var driver = analysisServer.driverMap.remove(folder);
- driver.dispose();
+ driver?.dispose();
}
List<HighlightRegion> _computeHighlightRegions(CompilationUnit unit) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index cf3de34..7799a3b 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -202,8 +202,14 @@
length,
);
try {
- var processor = AssistProcessor(context);
- var assists = await processor.compute();
+ List<Assist> assists;
+ try {
+ var processor = AssistProcessor(context);
+ assists = await processor.compute();
+ } on InconsistentAnalysisException {
+ assists = [];
+ }
+
assists.sort(Assist.SORT_BY_RELEVANCE);
for (var assist in assists) {
changes.add(assist.change);
@@ -605,6 +611,8 @@
List<Fix> fixes;
try {
fixes = await DartFixContributor().computeFixes(context);
+ } on InconsistentAnalysisException {
+ fixes = [];
} catch (exception, stackTrace) {
var parametersFile = '''
offset: $offset
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index c0aa0da..a5f55a1 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -706,7 +706,6 @@
@override
ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
String defaultPackageFilePath;
- String defaultPackagesDirectoryPath;
var path = (analysisServer.contextManager as ContextManagerImpl)
.normalizedPackageRoots[folder.path];
if (path != null) {
@@ -714,8 +713,6 @@
if (resource.exists) {
if (resource is File) {
defaultPackageFilePath = path;
- } else {
- defaultPackagesDirectoryPath = path;
}
}
}
@@ -723,7 +720,6 @@
var builderOptions = ContextBuilderOptions();
builderOptions.defaultOptions = options;
builderOptions.defaultPackageFilePath = defaultPackageFilePath;
- builderOptions.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
var builder = ContextBuilder(
resourceProvider, analysisServer.sdkManager, null,
options: builderOptions);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index ef43347..53d1eec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -6,8 +6,8 @@
/// completion.
import 'dart:math' as math;
-import 'package:analysis_server/src/protocol_server.dart'
- show ElementKind, convertElementToElementKind;
+import 'package:analysis_server/src/protocol_server.dart' as protocol
+ show ElementKind;
import 'package:analysis_server/src/services/completion/dart/relevance_tables.g.dart';
import 'package:analysis_server/src/utilities/extensions/element.dart';
import 'package:analyzer/dart/ast/ast.dart';
@@ -17,6 +17,7 @@
ClassElement,
ConstructorElement,
Element,
+ ElementKind,
FieldElement,
LibraryElement,
PropertyAccessorElement,
@@ -79,6 +80,57 @@
return type;
}
+ /// Return the element kind used to compute relevance for the given [element].
+ /// This differs from the kind returned to the client in that getters and
+ /// setters are always mapped into a different kind: FIELD for getters and
+ /// setters declared in a class or extension, and TOP_LEVEL_VARIABLE for
+ /// top-level getters and setters.
+ protocol.ElementKind computeElementKind(Element element) {
+ if (element is LibraryElement) {
+ return protocol.ElementKind.PREFIX;
+ } else if (element is ClassElement) {
+ if (element.isEnum) {
+ return protocol.ElementKind.ENUM;
+ } else if (element.isMixin) {
+ return protocol.ElementKind.MIXIN;
+ }
+ return protocol.ElementKind.CLASS;
+ } else if (element is FieldElement && element.isEnumConstant) {
+ return protocol.ElementKind.ENUM_CONSTANT;
+ } else if (element is PropertyAccessorElement) {
+ element = (element as PropertyAccessorElement).variable;
+ }
+ var kind = element.kind;
+ if (kind == ElementKind.CONSTRUCTOR) {
+ return protocol.ElementKind.CONSTRUCTOR;
+ } else if (kind == ElementKind.EXTENSION) {
+ return protocol.ElementKind.EXTENSION;
+ } else if (kind == ElementKind.FIELD) {
+ return protocol.ElementKind.FIELD;
+ } else if (kind == ElementKind.FUNCTION) {
+ return protocol.ElementKind.FUNCTION;
+ } else if (kind == ElementKind.FUNCTION_TYPE_ALIAS) {
+ return protocol.ElementKind.FUNCTION_TYPE_ALIAS;
+ } else if (kind == ElementKind.GENERIC_FUNCTION_TYPE) {
+ return protocol.ElementKind.FUNCTION_TYPE_ALIAS;
+ } else if (kind == ElementKind.LABEL) {
+ return protocol.ElementKind.LABEL;
+ } else if (kind == ElementKind.LOCAL_VARIABLE) {
+ return protocol.ElementKind.LOCAL_VARIABLE;
+ } else if (kind == ElementKind.METHOD) {
+ return protocol.ElementKind.METHOD;
+ } else if (kind == ElementKind.PARAMETER) {
+ return protocol.ElementKind.PARAMETER;
+ } else if (kind == ElementKind.PREFIX) {
+ return protocol.ElementKind.PREFIX;
+ } else if (kind == ElementKind.TOP_LEVEL_VARIABLE) {
+ return protocol.ElementKind.TOP_LEVEL_VARIABLE;
+ } else if (kind == ElementKind.TYPE_PARAMETER) {
+ return protocol.ElementKind.TYPE_PARAMETER;
+ }
+ return protocol.ElementKind.UNKNOWN;
+ }
+
/// Return the value of the _context type_ feature for an element with the
/// given [elementType] when completing in a location with the given
/// [contextType].
@@ -114,13 +166,7 @@
if (locationTable == null) {
return -1.0;
}
- ElementKind kind;
- if (element is LibraryElement) {
- kind = ElementKind.PREFIX;
- } else {
- kind = convertElementToElementKind(element);
- }
- var range = locationTable[kind];
+ var range = locationTable[computeElementKind(element)];
if (range == null) {
return 0.0;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart b/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
index 561608f..e461203 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/relevance_tables.g.dart
@@ -16,7 +16,8 @@
const elementKindRelevance = {
'Annotation_name': {
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.042),
- ElementKind.GETTER: ProbabilityRange(lower: 0.042, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.042, upper: 1.000),
},
'ArgumentList_annotation_named': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.979),
@@ -28,7 +29,7 @@
},
'ArgumentList_constructorRedirect_named': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.041),
- ElementKind.GETTER: ProbabilityRange(lower: 0.041, upper: 0.044),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.041, upper: 0.044),
ElementKind.ENUM: ProbabilityRange(lower: 0.044, upper: 0.047),
ElementKind.CLASS: ProbabilityRange(lower: 0.047, upper: 0.050),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.050, upper: 0.064),
@@ -36,7 +37,7 @@
},
'ArgumentList_constructorRedirect_unnamed': {
ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.199),
- ElementKind.GETTER: ProbabilityRange(lower: 0.199, upper: 0.201),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.199, upper: 0.201),
ElementKind.METHOD: ProbabilityRange(lower: 0.201, upper: 0.206),
ElementKind.ENUM: ProbabilityRange(lower: 0.206, upper: 0.212),
ElementKind.CLASS: ProbabilityRange(lower: 0.212, upper: 0.230),
@@ -47,9 +48,11 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.492),
ElementKind.PREFIX: ProbabilityRange(lower: 0.492, upper: 0.493),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.493, upper: 0.495),
- ElementKind.ENUM: ProbabilityRange(lower: 0.495, upper: 0.507),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.507, upper: 0.536),
- ElementKind.GETTER: ProbabilityRange(lower: 0.536, upper: 0.574),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.495, upper: 0.504),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.504, upper: 0.516),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.516, upper: 0.545),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.545, upper: 0.574),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.574, upper: 0.642),
ElementKind.CLASS: ProbabilityRange(lower: 0.642, upper: 0.731),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.731, upper: 1.000),
@@ -58,9 +61,11 @@
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.617),
ElementKind.METHOD: ProbabilityRange(lower: 0.617, upper: 0.622),
ElementKind.ENUM: ProbabilityRange(lower: 0.622, upper: 0.630),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.630, upper: 0.646),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.646, upper: 0.684),
- ElementKind.GETTER: ProbabilityRange(lower: 0.684, upper: 0.734),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.630, upper: 0.641),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.641, upper: 0.656),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.656, upper: 0.694),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.694, upper: 0.734),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.734, upper: 0.811),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.811, upper: 0.905),
ElementKind.CLASS: ProbabilityRange(lower: 0.905, upper: 1.000),
@@ -69,15 +74,17 @@
ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.616),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.616, upper: 0.648),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.648, upper: 0.792),
- ElementKind.GETTER: ProbabilityRange(lower: 0.792, upper: 1.000),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.792, upper: 1.000),
},
'ArgumentList_function_unnamed': {
- ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.220),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.220, upper: 0.227),
- ElementKind.ENUM: ProbabilityRange(lower: 0.227, upper: 0.237),
- ElementKind.CLASS: ProbabilityRange(lower: 0.237, upper: 0.255),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.255, upper: 0.280),
- ElementKind.GETTER: ProbabilityRange(lower: 0.280, upper: 0.347),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.216),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.216, upper: 0.222),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.222, upper: 0.229),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.229, upper: 0.239),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.239, upper: 0.257),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.257, upper: 0.282),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.282, upper: 0.347),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.347, upper: 0.583),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.583, upper: 1.000),
},
@@ -85,36 +92,40 @@
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.549),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.549, upper: 0.552),
ElementKind.METHOD: ProbabilityRange(lower: 0.552, upper: 0.556),
- ElementKind.ENUM: ProbabilityRange(lower: 0.556, upper: 0.569),
- ElementKind.CLASS: ProbabilityRange(lower: 0.569, upper: 0.627),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.627, upper: 0.686),
- ElementKind.GETTER: ProbabilityRange(lower: 0.686, upper: 0.764),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.556, upper: 0.566),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.566, upper: 0.579),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.579, upper: 0.637),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.637, upper: 0.696),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.696, upper: 0.764),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.764, upper: 0.854),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.854, upper: 1.000),
},
'ArgumentList_method_unnamed': {
ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.388),
- ElementKind.SETTER: ProbabilityRange(lower: 0.388, upper: 0.388),
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.388, upper: 0.388),
ElementKind.PREFIX: ProbabilityRange(lower: 0.388, upper: 0.389),
ElementKind.ENUM: ProbabilityRange(lower: 0.389, upper: 0.395),
ElementKind.METHOD: ProbabilityRange(lower: 0.395, upper: 0.403),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.403, upper: 0.426),
ElementKind.CLASS: ProbabilityRange(lower: 0.426, upper: 0.453),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.453, upper: 0.511),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.511, upper: 0.625),
- ElementKind.GETTER: ProbabilityRange(lower: 0.625, upper: 0.747),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.453, upper: 0.484),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.484, upper: 0.542),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.542, upper: 0.633),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.633, upper: 0.747),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.747, upper: 1.000),
},
'ArgumentList_widgetConstructor_named': {
- ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.352),
- ElementKind.PREFIX: ProbabilityRange(lower: 0.352, upper: 0.353),
+ ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.353),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.353, upper: 0.355),
- ElementKind.METHOD: ProbabilityRange(lower: 0.355, upper: 0.368),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.368, upper: 0.387),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.387, upper: 0.422),
- ElementKind.ENUM: ProbabilityRange(lower: 0.422, upper: 0.482),
- ElementKind.GETTER: ProbabilityRange(lower: 0.482, upper: 0.552),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.355, upper: 0.363),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.363, upper: 0.376),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.376, upper: 0.395),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.395, upper: 0.430),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.430, upper: 0.490),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.490, upper: 0.552),
ElementKind.CLASS: ProbabilityRange(lower: 0.552, upper: 0.636),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.636, upper: 1.000),
},
@@ -123,10 +134,12 @@
ElementKind.PREFIX: ProbabilityRange(lower: 0.462, upper: 0.464),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.464, upper: 0.470),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.470, upper: 0.476),
- ElementKind.METHOD: ProbabilityRange(lower: 0.476, upper: 0.492),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.492, upper: 0.542),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.542, upper: 0.613),
- ElementKind.GETTER: ProbabilityRange(lower: 0.613, upper: 0.757),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.476, upper: 0.485),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.485, upper: 0.501),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.501, upper: 0.552),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.552, upper: 0.622),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.622, upper: 0.757),
ElementKind.CLASS: ProbabilityRange(lower: 0.757, upper: 1.000),
},
'AsExpression_type': {
@@ -145,67 +158,78 @@
},
'AssertStatement_condition': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.144),
- ElementKind.METHOD: ProbabilityRange(lower: 0.144, upper: 0.179),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.179, upper: 0.230),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.230, upper: 0.346),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.346, upper: 0.644),
- ElementKind.GETTER: ProbabilityRange(lower: 0.644, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.144, upper: 0.150),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.150, upper: 0.185),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.185, upper: 0.236),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.236, upper: 0.352),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.352, upper: 0.650),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.650, upper: 1.000),
},
'AssertStatement_message': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 1.000),
},
'AssignmentExpression_rightHandSide': {
- ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.305),
- ElementKind.PREFIX: ProbabilityRange(lower: 0.305, upper: 0.306),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.306, upper: 0.317),
- ElementKind.METHOD: ProbabilityRange(lower: 0.317, upper: 0.329),
- ElementKind.ENUM: ProbabilityRange(lower: 0.329, upper: 0.349),
- ElementKind.CLASS: ProbabilityRange(lower: 0.349, upper: 0.395),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.395, upper: 0.489),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.489, upper: 0.600),
- ElementKind.GETTER: ProbabilityRange(lower: 0.600, upper: 0.739),
+ ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.306),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.306, upper: 0.315),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.315, upper: 0.326),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.326, upper: 0.338),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.338, upper: 0.358),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.358, upper: 0.403),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.403, upper: 0.497),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.497, upper: 0.608),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.608, upper: 0.739),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.739, upper: 1.000),
},
'AwaitExpression_expression': {
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.022),
ElementKind.PREFIX: ProbabilityRange(lower: 0.022, upper: 0.049),
- ElementKind.METHOD: ProbabilityRange(lower: 0.049, upper: 0.144),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.144, upper: 0.292),
- ElementKind.CLASS: ProbabilityRange(lower: 0.292, upper: 0.450),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.450, upper: 0.608),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.608, upper: 0.772),
- ElementKind.GETTER: ProbabilityRange(lower: 0.772, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.049, upper: 0.086),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.086, upper: 0.181),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.181, upper: 0.329),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.329, upper: 0.487),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.487, upper: 0.645),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.645, upper: 0.809),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.809, upper: 1.000),
},
'BinaryExpression_!=_rightOperand': {
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.874),
ElementKind.PREFIX: ProbabilityRange(lower: 0.874, upper: 0.875),
ElementKind.METHOD: ProbabilityRange(lower: 0.875, upper: 0.875),
- ElementKind.CLASS: ProbabilityRange(lower: 0.875, upper: 0.886),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.886, upper: 0.903),
- ElementKind.ENUM: ProbabilityRange(lower: 0.903, upper: 0.921),
- ElementKind.GETTER: ProbabilityRange(lower: 0.921, upper: 0.957),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.875, upper: 0.878),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.878, upper: 0.889),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.889, upper: 0.906),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.906, upper: 0.924),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.924, upper: 0.957),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.957, upper: 1.000),
},
'BinaryExpression_%_rightOperand': {
ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.722),
ElementKind.MIXIN: ProbabilityRange(lower: 0.722, upper: 0.728),
- ElementKind.CLASS: ProbabilityRange(lower: 0.728, upper: 0.755),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.755, upper: 0.788),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.788, upper: 0.851),
- ElementKind.GETTER: ProbabilityRange(lower: 0.851, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.728, upper: 0.745),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.745, upper: 0.772),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.772, upper: 0.805),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.805, upper: 0.868),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.868, upper: 1.000),
},
'BinaryExpression_&&_rightOperand': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.107),
ElementKind.METHOD: ProbabilityRange(lower: 0.107, upper: 0.112),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.112, upper: 0.122),
- ElementKind.CLASS: ProbabilityRange(lower: 0.122, upper: 0.137),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.137, upper: 0.259),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.259, upper: 0.439),
- ElementKind.GETTER: ProbabilityRange(lower: 0.439, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.112, upper: 0.117),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.117, upper: 0.128),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.128, upper: 0.142),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.142, upper: 0.264),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.264, upper: 0.445),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.445, upper: 1.000),
},
'BinaryExpression_&_rightOperand': {
ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.285),
- ElementKind.GETTER: ProbabilityRange(lower: 0.285, upper: 0.390),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.285, upper: 0.390),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.390, upper: 0.494),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.494, upper: 0.703),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.703, upper: 1.000),
@@ -217,9 +241,11 @@
ElementKind.CLASS: ProbabilityRange(lower: 0.627, upper: 0.636),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.636, upper: 0.651),
ElementKind.PREFIX: ProbabilityRange(lower: 0.651, upper: 0.672),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.672, upper: 0.722),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.722, upper: 0.851),
- ElementKind.GETTER: ProbabilityRange(lower: 0.851, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.672, upper: 0.702),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.702, upper: 0.751),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.751, upper: 0.870),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.870, upper: 1.000),
},
'BinaryExpression_+_rightOperand': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.508),
@@ -227,8 +253,10 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.510, upper: 0.517),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.517, upper: 0.532),
ElementKind.CLASS: ProbabilityRange(lower: 0.532, upper: 0.556),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.556, upper: 0.675),
- ElementKind.GETTER: ProbabilityRange(lower: 0.675, upper: 0.829),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.556, upper: 0.582),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.582, upper: 0.701),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.701, upper: 0.829),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.829, upper: 1.000),
},
'BinaryExpression_-_rightOperand': {
@@ -237,8 +265,10 @@
ElementKind.FUNCTION: ProbabilityRange(lower: 0.488, upper: 0.490),
ElementKind.METHOD: ProbabilityRange(lower: 0.490, upper: 0.499),
ElementKind.CLASS: ProbabilityRange(lower: 0.499, upper: 0.515),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.515, upper: 0.605),
- ElementKind.GETTER: ProbabilityRange(lower: 0.605, upper: 0.802),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.515, upper: 0.542),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.542, upper: 0.633),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.633, upper: 0.802),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.802, upper: 1.000),
},
'BinaryExpression_/_rightOperand': {
@@ -246,30 +276,36 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.768, upper: 0.768),
ElementKind.PREFIX: ProbabilityRange(lower: 0.768, upper: 0.771),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.771, upper: 0.777),
- ElementKind.CLASS: ProbabilityRange(lower: 0.777, upper: 0.786),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.786, upper: 0.822),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.822, upper: 0.910),
- ElementKind.GETTER: ProbabilityRange(lower: 0.910, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.777, upper: 0.785),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.785, upper: 0.793),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.793, upper: 0.830),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.830, upper: 0.912),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.912, upper: 1.000),
},
'BinaryExpression_<<_rightOperand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.756),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.756, upper: 0.854),
- ElementKind.GETTER: ProbabilityRange(lower: 0.854, upper: 1.000),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.854, upper: 1.000),
},
'BinaryExpression_<=_rightOperand': {
ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.609),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.609, upper: 0.721),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.721, upper: 0.848),
- ElementKind.GETTER: ProbabilityRange(lower: 0.848, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.609, upper: 0.621),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.621, upper: 0.733),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.733, upper: 0.861),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.861, upper: 1.000),
},
'BinaryExpression_<_rightOperand': {
ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.424),
ElementKind.METHOD: ProbabilityRange(lower: 0.424, upper: 0.426),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.426, upper: 0.427),
ElementKind.CLASS: ProbabilityRange(lower: 0.427, upper: 0.439),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.439, upper: 0.557),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.557, upper: 0.771),
- ElementKind.GETTER: ProbabilityRange(lower: 0.771, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.439, upper: 0.461),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.461, upper: 0.580),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.580, upper: 0.785),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.785, upper: 1.000),
},
'BinaryExpression_==_rightOperand': {
ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.568),
@@ -277,18 +313,22 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.568, upper: 0.568),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.568, upper: 0.569),
ElementKind.PREFIX: ProbabilityRange(lower: 0.569, upper: 0.569),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.569, upper: 0.593),
- ElementKind.CLASS: ProbabilityRange(lower: 0.593, upper: 0.631),
- ElementKind.GETTER: ProbabilityRange(lower: 0.631, upper: 0.679),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.569, upper: 0.577),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.577, upper: 0.601),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.601, upper: 0.639),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.639, upper: 0.679),
ElementKind.ENUM: ProbabilityRange(lower: 0.679, upper: 0.807),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.807, upper: 1.000),
},
'BinaryExpression_>=_rightOperand': {
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.000, upper: 0.714),
ElementKind.CLASS: ProbabilityRange(lower: 0.714, upper: 0.731),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.731, upper: 0.792),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.792, upper: 0.854),
- ElementKind.GETTER: ProbabilityRange(lower: 0.854, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.731, upper: 0.761),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.761, upper: 0.821),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.821, upper: 0.884),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.884, upper: 1.000),
},
'BinaryExpression_>>_rightOperand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 1.000),
@@ -299,44 +339,52 @@
ElementKind.ENUM: ProbabilityRange(lower: 0.815, upper: 0.817),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.817, upper: 0.820),
ElementKind.CLASS: ProbabilityRange(lower: 0.820, upper: 0.828),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.828, upper: 0.868),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.868, upper: 0.928),
- ElementKind.GETTER: ProbabilityRange(lower: 0.928, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.828, upper: 0.850),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.850, upper: 0.890),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.890, upper: 0.939),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.939, upper: 1.000),
},
'BinaryExpression_??_rightOperand': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.665),
ElementKind.METHOD: ProbabilityRange(lower: 0.665, upper: 0.668),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.668, upper: 0.673),
- ElementKind.ENUM: ProbabilityRange(lower: 0.673, upper: 0.685),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.685, upper: 0.726),
- ElementKind.GETTER: ProbabilityRange(lower: 0.726, upper: 0.769),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.673, upper: 0.680),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.680, upper: 0.692),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.692, upper: 0.728),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.728, upper: 0.769),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.769, upper: 0.817),
ElementKind.CLASS: ProbabilityRange(lower: 0.817, upper: 0.871),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.871, upper: 1.000),
},
'BinaryExpression_^_rightOperand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.118),
- ElementKind.GETTER: ProbabilityRange(lower: 0.118, upper: 1.000),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.118, upper: 1.000),
},
'BinaryExpression_|_rightOperand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.143),
- ElementKind.GETTER: ProbabilityRange(lower: 0.143, upper: 0.429),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.143, upper: 0.429),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.429, upper: 1.000),
},
'BinaryExpression_||_rightOperand': {
- ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.143),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.143, upper: 0.147),
- ElementKind.CLASS: ProbabilityRange(lower: 0.147, upper: 0.167),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.167, upper: 0.380),
- ElementKind.GETTER: ProbabilityRange(lower: 0.380, upper: 0.666),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.141),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.141, upper: 0.145),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.145, upper: 0.149),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.149, upper: 0.169),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.169, upper: 0.382),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.382, upper: 0.666),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.666, upper: 1.000),
},
'BinaryExpression_~/_rightOperand': {
- ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 0.635),
- ElementKind.MIXIN: ProbabilityRange(lower: 0.635, upper: 0.648),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.648, upper: 0.686),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.686, upper: 0.792),
- ElementKind.GETTER: ProbabilityRange(lower: 0.792, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.629),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.629, upper: 0.642),
+ ElementKind.MIXIN: ProbabilityRange(lower: 0.642, upper: 0.654),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.654, upper: 0.692),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.692, upper: 0.799),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.799, upper: 1.000),
},
'Block_statement': {
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.537),
@@ -346,13 +394,14 @@
ElementKind.ENUM: ProbabilityRange(lower: 0.537, upper: 0.538),
ElementKind.MIXIN: ProbabilityRange(lower: 0.538, upper: 0.538),
ElementKind.PREFIX: ProbabilityRange(lower: 0.538, upper: 0.540),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.540, upper: 0.563),
- ElementKind.METHOD: ProbabilityRange(lower: 0.563, upper: 0.613),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.613, upper: 0.673),
- ElementKind.GETTER: ProbabilityRange(lower: 0.673, upper: 0.742),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.742, upper: 0.824),
- ElementKind.SETTER: ProbabilityRange(lower: 0.824, upper: 0.911),
- ElementKind.CLASS: ProbabilityRange(lower: 0.911, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.540, upper: 0.554),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.554, upper: 0.577),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.577, upper: 0.627),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.627, upper: 0.687),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.687, upper: 0.770),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.770, upper: 0.858),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.858, upper: 1.000),
},
'CatchClause_exceptionType': {
ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
@@ -372,16 +421,17 @@
},
'CommentReference_identifier': {
ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.001),
- ElementKind.SETTER: ProbabilityRange(lower: 0.001, upper: 0.001),
ElementKind.FUNCTION_TYPE_ALIAS:
- ProbabilityRange(lower: 0.001, upper: 0.003),
- ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.003, upper: 0.005),
- ElementKind.PREFIX: ProbabilityRange(lower: 0.005, upper: 0.009),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.009, upper: 0.022),
- ElementKind.METHOD: ProbabilityRange(lower: 0.022, upper: 0.056),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.056, upper: 0.114),
- ElementKind.ENUM: ProbabilityRange(lower: 0.114, upper: 0.177),
- ElementKind.GETTER: ProbabilityRange(lower: 0.177, upper: 0.456),
+ ProbabilityRange(lower: 0.001, upper: 0.002),
+ ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.002, upper: 0.004),
+ ElementKind.PREFIX: ProbabilityRange(lower: 0.004, upper: 0.008),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.008, upper: 0.012),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.012, upper: 0.026),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.026, upper: 0.060),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.060, upper: 0.118),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.118, upper: 0.181),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.181, upper: 0.456),
ElementKind.CLASS: ProbabilityRange(lower: 0.456, upper: 1.000),
},
'CompilationUnit_declaration': {
@@ -395,25 +445,27 @@
},
'ConditionalExpression_elseExpression': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.369),
- ElementKind.SETTER: ProbabilityRange(lower: 0.369, upper: 0.375),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.375, upper: 0.383),
- ElementKind.METHOD: ProbabilityRange(lower: 0.383, upper: 0.402),
- ElementKind.ENUM: ProbabilityRange(lower: 0.402, upper: 0.426),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.426, upper: 0.482),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.482, upper: 0.549),
- ElementKind.GETTER: ProbabilityRange(lower: 0.549, upper: 0.655),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.369, upper: 0.378),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.378, upper: 0.388),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.388, upper: 0.407),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.407, upper: 0.431),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.431, upper: 0.487),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.487, upper: 0.554),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.554, upper: 0.655),
ElementKind.CLASS: ProbabilityRange(lower: 0.655, upper: 0.790),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.790, upper: 1.000),
},
'ConditionalExpression_thenExpression': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.390),
- ElementKind.SETTER: ProbabilityRange(lower: 0.390, upper: 0.396),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.396, upper: 0.403),
- ElementKind.METHOD: ProbabilityRange(lower: 0.403, upper: 0.424),
- ElementKind.ENUM: ProbabilityRange(lower: 0.424, upper: 0.450),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.450, upper: 0.500),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.500, upper: 0.556),
- ElementKind.GETTER: ProbabilityRange(lower: 0.556, upper: 0.633),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.390, upper: 0.397),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.397, upper: 0.408),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.408, upper: 0.429),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.429, upper: 0.456),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.456, upper: 0.506),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.506, upper: 0.562),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.562, upper: 0.633),
ElementKind.CLASS: ProbabilityRange(lower: 0.633, upper: 0.776),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.776, upper: 1.000),
},
@@ -424,7 +476,9 @@
ElementKind.CLASS: ProbabilityRange(lower: 0.000, upper: 1.000),
},
'ConstructorFieldInitializer_expression': {
- ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.185),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.183),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.183, upper: 0.185),
ElementKind.METHOD: ProbabilityRange(lower: 0.185, upper: 0.188),
ElementKind.ENUM: ProbabilityRange(lower: 0.188, upper: 0.196),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.196, upper: 0.221),
@@ -436,7 +490,9 @@
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.694),
ElementKind.METHOD: ProbabilityRange(lower: 0.694, upper: 0.695),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.695, upper: 0.696),
- ElementKind.GETTER: ProbabilityRange(lower: 0.696, upper: 0.713),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.696, upper: 0.702),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.702, upper: 0.713),
ElementKind.ENUM: ProbabilityRange(lower: 0.713, upper: 0.760),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.760, upper: 0.827),
ElementKind.CLASS: ProbabilityRange(lower: 0.827, upper: 1.000),
@@ -450,18 +506,17 @@
ElementKind.FUNCTION_TYPE_ALIAS:
ProbabilityRange(lower: 0.386, upper: 0.386),
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.386, upper: 0.387),
- ElementKind.TOP_LEVEL_VARIABLE:
- ProbabilityRange(lower: 0.387, upper: 0.387),
ElementKind.MIXIN: ProbabilityRange(lower: 0.387, upper: 0.387),
ElementKind.PREFIX: ProbabilityRange(lower: 0.387, upper: 0.388),
- ElementKind.SETTER: ProbabilityRange(lower: 0.388, upper: 0.403),
- ElementKind.ENUM: ProbabilityRange(lower: 0.403, upper: 0.419),
- ElementKind.METHOD: ProbabilityRange(lower: 0.419, upper: 0.435),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.435, upper: 0.452),
- ElementKind.CLASS: ProbabilityRange(lower: 0.452, upper: 0.524),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.524, upper: 0.608),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.608, upper: 0.704),
- ElementKind.GETTER: ProbabilityRange(lower: 0.704, upper: 0.835),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.388, upper: 0.404),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.404, upper: 0.420),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.420, upper: 0.437),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.437, upper: 0.470),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.470, upper: 0.542),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.542, upper: 0.626),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.626, upper: 0.722),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.722, upper: 0.835),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.835, upper: 1.000),
},
'ExpressionFunctionBody_expression': {
@@ -469,27 +524,29 @@
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.162, upper: 0.163),
ElementKind.ENUM: ProbabilityRange(lower: 0.163, upper: 0.164),
ElementKind.PREFIX: ProbabilityRange(lower: 0.164, upper: 0.171),
- ElementKind.SETTER: ProbabilityRange(lower: 0.171, upper: 0.184),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.171, upper: 0.184),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.184, upper: 0.211),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.211, upper: 0.244),
ElementKind.CLASS: ProbabilityRange(lower: 0.244, upper: 0.286),
ElementKind.METHOD: ProbabilityRange(lower: 0.286, upper: 0.332),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.332, upper: 0.496),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.496, upper: 0.731),
- ElementKind.GETTER: ProbabilityRange(lower: 0.731, upper: 1.000),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.332, upper: 0.497),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.497, upper: 0.731),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.731, upper: 1.000),
},
'ExpressionStatement_expression': {
ElementKind.ENUM: ProbabilityRange(lower: 0.000, upper: 0.132),
ElementKind.MIXIN: ProbabilityRange(lower: 0.132, upper: 0.134),
ElementKind.PREFIX: ProbabilityRange(lower: 0.134, upper: 0.136),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.136, upper: 0.139),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.139, upper: 0.189),
- ElementKind.CLASS: ProbabilityRange(lower: 0.189, upper: 0.254),
- ElementKind.METHOD: ProbabilityRange(lower: 0.254, upper: 0.359),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.359, upper: 0.481),
- ElementKind.GETTER: ProbabilityRange(lower: 0.481, upper: 0.624),
- ElementKind.SETTER: ProbabilityRange(lower: 0.624, upper: 0.801),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.801, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.139, upper: 0.168),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.168, upper: 0.218),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.218, upper: 0.283),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.283, upper: 0.388),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.388, upper: 0.510),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.510, upper: 0.709),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.709, upper: 1.000),
},
'ExtendsClause_superclass': {
ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.000),
@@ -519,7 +576,9 @@
ElementKind.FUNCTION: ProbabilityRange(lower: 0.018, upper: 0.022),
ElementKind.PREFIX: ProbabilityRange(lower: 0.022, upper: 0.029),
ElementKind.CLASS: ProbabilityRange(lower: 0.029, upper: 0.037),
- ElementKind.GETTER: ProbabilityRange(lower: 0.037, upper: 0.287),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.037, upper: 0.076),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.076, upper: 0.287),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.287, upper: 0.606),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.606, upper: 1.000),
},
@@ -544,16 +603,19 @@
ElementKind.CLASS: ProbabilityRange(lower: 0.634, upper: 1.000),
},
'ForParts_condition': {
- ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.024),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.000, upper: 0.004),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.004, upper: 0.024),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.024, upper: 1.000),
},
'ForParts_updater': {
- ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.068),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.068),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.068, upper: 1.000),
},
'ForStatement_body': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.981),
- ElementKind.GETTER: ProbabilityRange(lower: 0.981, upper: 0.986),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.981, upper: 0.986),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.986, upper: 1.000),
},
'ForStatement_forLoopParts': {
@@ -564,7 +626,8 @@
ElementKind.ENUM: ProbabilityRange(lower: 0.538, upper: 0.539),
ElementKind.PREFIX: ProbabilityRange(lower: 0.539, upper: 0.541),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.541, upper: 0.551),
- ElementKind.SETTER: ProbabilityRange(lower: 0.551, upper: 0.561),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.551, upper: 0.561),
ElementKind.CLASS: ProbabilityRange(lower: 0.561, upper: 1.000),
},
'FormalParameterList_parameter': {
@@ -598,11 +661,13 @@
ElementKind.CLASS: ProbabilityRange(lower: 0.059, upper: 1.000),
},
'IfElement_condition': {
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.158),
- ElementKind.CLASS: ProbabilityRange(lower: 0.158, upper: 0.174),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.174, upper: 0.335),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.335, upper: 0.629),
- ElementKind.GETTER: ProbabilityRange(lower: 0.629, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.158),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.158, upper: 0.163),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.163, upper: 0.179),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.179, upper: 0.339),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.339, upper: 0.633),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.633, upper: 1.000),
},
'IfElement_elseElement': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.346),
@@ -613,7 +678,7 @@
ElementKind.PARAMETER: ProbabilityRange(lower: 0.215, upper: 0.222),
ElementKind.CLASS: ProbabilityRange(lower: 0.222, upper: 0.230),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.230, upper: 0.242),
- ElementKind.GETTER: ProbabilityRange(lower: 0.242, upper: 0.257),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.242, upper: 0.257),
ElementKind.METHOD: ProbabilityRange(lower: 0.257, upper: 0.284),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.284, upper: 1.000),
},
@@ -623,29 +688,33 @@
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.118, upper: 0.118),
ElementKind.ENUM: ProbabilityRange(lower: 0.118, upper: 0.118),
ElementKind.PREFIX: ProbabilityRange(lower: 0.118, upper: 0.119),
- ElementKind.METHOD: ProbabilityRange(lower: 0.119, upper: 0.129),
- ElementKind.CLASS: ProbabilityRange(lower: 0.129, upper: 0.145),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.145, upper: 0.167),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.167, upper: 0.389),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.389, upper: 0.688),
- ElementKind.GETTER: ProbabilityRange(lower: 0.688, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.119, upper: 0.127),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.127, upper: 0.137),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.137, upper: 0.153),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.153, upper: 0.175),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.175, upper: 0.397),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.397, upper: 0.696),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.696, upper: 1.000),
},
'IfStatement_elseStatement': {
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.969),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.000, upper: 0.968),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.968, upper: 0.969),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.969, upper: 0.970),
- ElementKind.SETTER: ProbabilityRange(lower: 0.970, upper: 0.973),
- ElementKind.CLASS: ProbabilityRange(lower: 0.973, upper: 0.976),
- ElementKind.GETTER: ProbabilityRange(lower: 0.976, upper: 0.982),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.970, upper: 0.973),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.973, upper: 0.982),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.982, upper: 0.991),
ElementKind.METHOD: ProbabilityRange(lower: 0.991, upper: 1.000),
},
'IfStatement_thenStatement': {
ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.935),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.935, upper: 0.936),
- ElementKind.CLASS: ProbabilityRange(lower: 0.936, upper: 0.938),
- ElementKind.SETTER: ProbabilityRange(lower: 0.938, upper: 0.943),
- ElementKind.METHOD: ProbabilityRange(lower: 0.943, upper: 0.952),
- ElementKind.GETTER: ProbabilityRange(lower: 0.952, upper: 0.965),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.935, upper: 0.936),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.936, upper: 0.937),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.937, upper: 0.939),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.939, upper: 0.948),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.948, upper: 0.965),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.965, upper: 0.981),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.981, upper: 1.000),
},
@@ -661,7 +730,9 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.656, upper: 0.657),
ElementKind.ENUM: ProbabilityRange(lower: 0.657, upper: 0.659),
ElementKind.CLASS: ProbabilityRange(lower: 0.659, upper: 0.664),
- ElementKind.GETTER: ProbabilityRange(lower: 0.664, upper: 0.761),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.664, upper: 0.670),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.670, upper: 0.761),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.761, upper: 0.863),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.863, upper: 1.000),
},
@@ -676,10 +747,12 @@
ElementKind.ENUM: ProbabilityRange(lower: 0.036, upper: 0.037),
ElementKind.METHOD: ProbabilityRange(lower: 0.037, upper: 0.044),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.044, upper: 0.074),
- ElementKind.CLASS: ProbabilityRange(lower: 0.074, upper: 0.198),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.198, upper: 0.389),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.389, upper: 0.635),
- ElementKind.GETTER: ProbabilityRange(lower: 0.635, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.074, upper: 0.133),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.133, upper: 0.257),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.257, upper: 0.447),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.447, upper: 0.693),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.693, upper: 1.000),
},
'IsExpression_type': {
ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.001),
@@ -691,13 +764,14 @@
ElementKind.CLASS: ProbabilityRange(lower: 0.013, upper: 1.000),
},
'ListLiteral_element': {
- ElementKind.SETTER: ProbabilityRange(lower: 0.000, upper: 0.324),
- ElementKind.PREFIX: ProbabilityRange(lower: 0.324, upper: 0.324),
+ ElementKind.PREFIX: ProbabilityRange(lower: 0.000, upper: 0.324),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.324, upper: 0.326),
- ElementKind.ENUM: ProbabilityRange(lower: 0.326, upper: 0.331),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.331, upper: 0.338),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.338, upper: 0.348),
- ElementKind.GETTER: ProbabilityRange(lower: 0.348, upper: 0.361),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.326, upper: 0.329),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.329, upper: 0.333),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.333, upper: 0.340),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.340, upper: 0.350),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.350, upper: 0.361),
ElementKind.METHOD: ProbabilityRange(lower: 0.361, upper: 0.379),
ElementKind.CLASS: ProbabilityRange(lower: 0.379, upper: 0.406),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.406, upper: 1.000),
@@ -707,10 +781,12 @@
ElementKind.METHOD: ProbabilityRange(lower: 0.814, upper: 0.814),
ElementKind.ENUM: ProbabilityRange(lower: 0.814, upper: 0.816),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.816, upper: 0.818),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.818, upper: 0.823),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.823, upper: 0.829),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.829, upper: 0.849),
- ElementKind.GETTER: ProbabilityRange(lower: 0.849, upper: 0.884),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.818, upper: 0.823),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.823, upper: 0.828),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.828, upper: 0.833),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.833, upper: 0.854),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.854, upper: 0.884),
ElementKind.CLASS: ProbabilityRange(lower: 0.884, upper: 1.000),
},
'MethodDeclaration_returnType': {
@@ -737,42 +813,45 @@
ElementKind.MIXIN: ProbabilityRange(lower: 0.000, upper: 0.218),
ElementKind.ENUM: ProbabilityRange(lower: 0.218, upper: 0.219),
ElementKind.PREFIX: ProbabilityRange(lower: 0.219, upper: 0.221),
- ElementKind.SETTER: ProbabilityRange(lower: 0.221, upper: 0.223),
- ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.223, upper: 0.226),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.226, upper: 0.231),
- ElementKind.CLASS: ProbabilityRange(lower: 0.231, upper: 0.277),
- ElementKind.METHOD: ProbabilityRange(lower: 0.277, upper: 0.334),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.334, upper: 0.517),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.517, upper: 0.731),
- ElementKind.GETTER: ProbabilityRange(lower: 0.731, upper: 1.000),
+ ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.221, upper: 0.224),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.224, upper: 0.228),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.228, upper: 0.274),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.274, upper: 0.331),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.331, upper: 0.403),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.403, upper: 0.586),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.586, upper: 0.786),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.786, upper: 1.000),
},
'PrefixExpression_!_operand': {
ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.062),
ElementKind.METHOD: ProbabilityRange(lower: 0.062, upper: 0.090),
- ElementKind.CLASS: ProbabilityRange(lower: 0.090, upper: 0.139),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.139, upper: 0.326),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.326, upper: 0.582),
- ElementKind.GETTER: ProbabilityRange(lower: 0.582, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.090, upper: 0.124),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.124, upper: 0.173),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.173, upper: 0.360),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.360, upper: 0.616),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.616, upper: 1.000),
},
'PrefixExpression_++_operand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.035),
- ElementKind.GETTER: ProbabilityRange(lower: 0.035, upper: 0.123),
- ElementKind.SETTER: ProbabilityRange(lower: 0.123, upper: 0.351),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.035, upper: 0.351),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.351, upper: 1.000),
},
'PrefixExpression_--_operand': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.063),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.063, upper: 0.313),
- ElementKind.SETTER: ProbabilityRange(lower: 0.313, upper: 0.625),
- ElementKind.GETTER: ProbabilityRange(lower: 0.625, upper: 1.000),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.313, upper: 1.000),
},
'PrefixExpression_-_operand': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.830),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.830, upper: 0.832),
ElementKind.PREFIX: ProbabilityRange(lower: 0.832, upper: 0.839),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.839, upper: 0.857),
- ElementKind.CLASS: ProbabilityRange(lower: 0.857, upper: 0.883),
- ElementKind.GETTER: ProbabilityRange(lower: 0.883, upper: 0.930),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.857, upper: 0.877),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.877, upper: 0.902),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.902, upper: 0.930),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.930, upper: 1.000),
},
'PrefixExpression_~_operand': {
@@ -780,18 +859,18 @@
},
'PropertyAccess_propertyName': {
ElementKind.METHOD: ProbabilityRange(lower: 0.000, upper: 0.002),
- ElementKind.SETTER: ProbabilityRange(lower: 0.002, upper: 0.103),
- ElementKind.GETTER: ProbabilityRange(lower: 0.103, upper: 1.000),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.002, upper: 1.000),
},
'ReturnStatement_expression': {
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.243),
- ElementKind.SETTER: ProbabilityRange(lower: 0.243, upper: 0.243),
- ElementKind.PREFIX: ProbabilityRange(lower: 0.243, upper: 0.247),
- ElementKind.ENUM: ProbabilityRange(lower: 0.247, upper: 0.254),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.254, upper: 0.271),
- ElementKind.METHOD: ProbabilityRange(lower: 0.271, upper: 0.295),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.295, upper: 0.348),
- ElementKind.GETTER: ProbabilityRange(lower: 0.348, upper: 0.406),
+ ElementKind.PREFIX: ProbabilityRange(lower: 0.243, upper: 0.246),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.246, upper: 0.254),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.254, upper: 0.262),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.262, upper: 0.279),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.279, upper: 0.303),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.303, upper: 0.352),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.352, upper: 0.406),
ElementKind.CLASS: ProbabilityRange(lower: 0.406, upper: 0.466),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.466, upper: 0.564),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.564, upper: 1.000),
@@ -802,9 +881,11 @@
ElementKind.FUNCTION: ProbabilityRange(lower: 0.974, upper: 0.974),
ElementKind.PREFIX: ProbabilityRange(lower: 0.974, upper: 0.974),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.974, upper: 0.975),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.975, upper: 0.978),
- ElementKind.ENUM: ProbabilityRange(lower: 0.978, upper: 0.983),
- ElementKind.GETTER: ProbabilityRange(lower: 0.983, upper: 0.991),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.975, upper: 0.976),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.976, upper: 0.979),
+ ElementKind.ENUM: ProbabilityRange(lower: 0.979, upper: 0.985),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.985, upper: 0.991),
ElementKind.CLASS: ProbabilityRange(lower: 0.991, upper: 1.000),
},
'ShowCombinator_shownName': {
@@ -821,10 +902,12 @@
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.335, upper: 0.349),
ElementKind.CLASS: ProbabilityRange(lower: 0.349, upper: 0.379),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.379, upper: 0.446),
- ElementKind.METHOD: ProbabilityRange(lower: 0.446, upper: 0.535),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.535, upper: 0.636),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.636, upper: 0.740),
- ElementKind.GETTER: ProbabilityRange(lower: 0.740, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.446, upper: 0.520),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.520, upper: 0.610),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.610, upper: 0.710),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.710, upper: 0.814),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.814, upper: 1.000),
},
'Statement': {
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.599),
@@ -834,36 +917,42 @@
ElementKind.ENUM: ProbabilityRange(lower: 0.600, upper: 0.600),
ElementKind.MIXIN: ProbabilityRange(lower: 0.600, upper: 0.601),
ElementKind.PREFIX: ProbabilityRange(lower: 0.601, upper: 0.602),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.602, upper: 0.622),
- ElementKind.METHOD: ProbabilityRange(lower: 0.622, upper: 0.665),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.665, upper: 0.715),
- ElementKind.GETTER: ProbabilityRange(lower: 0.715, upper: 0.773),
- ElementKind.SETTER: ProbabilityRange(lower: 0.773, upper: 0.845),
- ElementKind.CLASS: ProbabilityRange(lower: 0.845, upper: 0.919),
- ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.919, upper: 1.000),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.602, upper: 0.613),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.613, upper: 0.634),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.634, upper: 0.677),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.677, upper: 0.727),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.727, upper: 0.800),
+ ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.800, upper: 0.881),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.881, upper: 1.000),
},
'SwitchCase_expression': {
- ElementKind.GETTER: ProbabilityRange(lower: 0.000, upper: 0.525),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.000, upper: 0.508),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.508, upper: 0.525),
ElementKind.CLASS: ProbabilityRange(lower: 0.525, upper: 0.668),
ElementKind.ENUM: ProbabilityRange(lower: 0.668, upper: 1.000),
},
'SwitchMember_statement': {
ElementKind.UNKNOWN: ProbabilityRange(lower: 0.000, upper: 0.683),
ElementKind.MIXIN: ProbabilityRange(lower: 0.683, upper: 0.683),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.683, upper: 0.690),
- ElementKind.CLASS: ProbabilityRange(lower: 0.690, upper: 0.701),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.701, upper: 0.713),
- ElementKind.SETTER: ProbabilityRange(lower: 0.713, upper: 0.726),
- ElementKind.METHOD: ProbabilityRange(lower: 0.726, upper: 0.742),
- ElementKind.GETTER: ProbabilityRange(lower: 0.742, upper: 0.759),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.683, upper: 0.685),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.685, upper: 0.691),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.691, upper: 0.703),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.703, upper: 0.715),
+ ElementKind.METHOD: ProbabilityRange(lower: 0.715, upper: 0.730),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.730, upper: 0.759),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.759, upper: 1.000),
},
'SwitchStatement_expression': {
ElementKind.TYPE_PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.010),
ElementKind.FUNCTION: ProbabilityRange(lower: 0.010, upper: 0.012),
ElementKind.METHOD: ProbabilityRange(lower: 0.012, upper: 0.016),
- ElementKind.CLASS: ProbabilityRange(lower: 0.016, upper: 0.031),
- ElementKind.GETTER: ProbabilityRange(lower: 0.031, upper: 0.212),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.016, upper: 0.023),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.023, upper: 0.039),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.039, upper: 0.212),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.212, upper: 0.516),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.516, upper: 1.000),
},
@@ -904,10 +993,12 @@
ElementKind.PREFIX: ProbabilityRange(lower: 0.452, upper: 0.455),
ElementKind.ENUM: ProbabilityRange(lower: 0.455, upper: 0.459),
ElementKind.METHOD: ProbabilityRange(lower: 0.459, upper: 0.471),
- ElementKind.FUNCTION: ProbabilityRange(lower: 0.471, upper: 0.497),
- ElementKind.PARAMETER: ProbabilityRange(lower: 0.497, upper: 0.560),
- ElementKind.CLASS: ProbabilityRange(lower: 0.560, upper: 0.630),
- ElementKind.GETTER: ProbabilityRange(lower: 0.630, upper: 0.712),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.471, upper: 0.489),
+ ElementKind.FUNCTION: ProbabilityRange(lower: 0.489, upper: 0.515),
+ ElementKind.PARAMETER: ProbabilityRange(lower: 0.515, upper: 0.578),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.578, upper: 0.641),
+ ElementKind.CLASS: ProbabilityRange(lower: 0.641, upper: 0.712),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.712, upper: 0.794),
ElementKind.CONSTRUCTOR: ProbabilityRange(lower: 0.794, upper: 1.000),
},
@@ -917,7 +1008,7 @@
},
'WhileStatement_condition': {
ElementKind.PARAMETER: ProbabilityRange(lower: 0.000, upper: 0.083),
- ElementKind.GETTER: ProbabilityRange(lower: 0.083, upper: 0.109),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.083, upper: 0.109),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.109, upper: 1.000),
},
'WithClause_mixinType': {
@@ -926,7 +1017,9 @@
},
'YieldStatement_expression': {
ElementKind.FUNCTION: ProbabilityRange(lower: 0.000, upper: 0.065),
- ElementKind.GETTER: ProbabilityRange(lower: 0.065, upper: 0.086),
+ ElementKind.TOP_LEVEL_VARIABLE:
+ ProbabilityRange(lower: 0.065, upper: 0.068),
+ ElementKind.FIELD: ProbabilityRange(lower: 0.068, upper: 0.086),
ElementKind.PARAMETER: ProbabilityRange(lower: 0.086, upper: 0.122),
ElementKind.LOCAL_VARIABLE: ProbabilityRange(lower: 0.122, upper: 0.161),
ElementKind.METHOD: ProbabilityRange(lower: 0.161, upper: 0.309),
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 1b83baf..3076e34 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -36,11 +36,11 @@
import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
import 'package:analysis_server/src/services/correction/dart/split_and_condition.dart';
import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analysis_server/src/services/correction/name_suggestion.dart';
import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
import 'package:analysis_server/src/services/correction/util.dart';
-import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/precedence.dart';
@@ -65,7 +65,43 @@
/// The computer for Dart assists.
class AssistProcessor extends BaseProcessor {
+ /// A map that can be used to look up the names of the lints for which a given
+ /// [CorrectionProducer] will be used.
+ static final Map<ProducerGenerator, Set<String>> lintRuleMap =
+ createLintRuleMap();
+
+ /// A list of the generators used to produce assists.
+ static const List<ProducerGenerator> generators = [
+ AddDiagnosticPropertyReference.newInstance,
+ AddReturnType.newInstance,
+ AddTypeAnnotation.newInstance,
+ ConvertAddAllToSpread.newInstance,
+ ConvertConditionalExpressionToIfElement.newInstance,
+ ConvertDocumentationIntoLine.newInstance,
+ ConvertMapFromIterableToForLiteral.newInstance,
+ ConvertToDoubleQuotes.newInstance,
+ ConvertToSingleQuotes.newInstance,
+ ConvertToExpressionFunctionBody.newInstance,
+ ConvertToGenericFunctionSyntax.newInstance,
+ ConvertToIntLiteral.newInstance,
+ ConvertToListLiteral.newInstance,
+ ConvertToMapLiteral.newInstance,
+ ConvertToNullAware.newInstance,
+ ConvertToPackageImport.newInstance,
+ ConvertToRelativeImport.newInstance,
+ ConvertToSetLiteral.newInstance,
+ ExchangeOperands.newInstance,
+ InlineInvocation.newInstance,
+ RemoveTypeAnnotation.newInstance,
+ ReplaceWithVar.newInstance,
+ ShadowField.newInstance,
+ SortChildPropertyLast.newInstance,
+ SplitAndCondition.newInstance,
+ UseCurlyBraces.newInstance,
+ ];
+
final DartAssistContext context;
+
final List<Assist> assists = <Assist>[];
AssistProcessor(this.context)
@@ -194,115 +230,19 @@
if (!setupSuccess) {
return;
}
+ for (var generator in generators) {
+ var ruleNames = lintRuleMap[generator] ?? {};
+ if (!_containsErrorCode(ruleNames)) {
+ var producer = generator();
+ producer.configure(context);
- Future<void> compute(CorrectionProducer producer) async {
- producer.configure(context);
+ var builder = _newDartChangeBuilder();
+ await producer.compute(builder);
- var builder = _newDartChangeBuilder();
- await producer.compute(builder);
-
- _addAssistFromBuilder(builder, producer.assistKind,
- args: producer.assistArguments);
- }
-
- Future<void> computeIfNotErrorCode(
- CorrectionProducer producer,
- Set<String> errorCodes,
- ) async {
- if (!_containsErrorCode(errorCodes)) {
- await compute(producer);
+ _addAssistFromBuilder(builder, producer.assistKind,
+ args: producer.assistArguments);
}
}
-
- await computeIfNotErrorCode(
- AddReturnType(),
- {LintNames.always_declare_return_types},
- );
- await computeIfNotErrorCode(
- AddDiagnosticPropertyReference(),
- {LintNames.diagnostic_describe_all_properties},
- );
- await computeIfNotErrorCode(
- AddTypeAnnotation(),
- {LintNames.always_specify_types, LintNames.type_annotate_public_apis},
- );
- await computeIfNotErrorCode(
- ConvertConditionalExpressionToIfElement(),
- {LintNames.prefer_if_elements_to_conditional_expressions},
- );
- await computeIfNotErrorCode(
- ConvertDocumentationIntoLine(),
- {LintNames.slash_for_doc_comments},
- );
- await computeIfNotErrorCode(
- ConvertMapFromIterableToForLiteral(),
- {LintNames.prefer_for_elements_to_map_fromIterable},
- );
- await compute(ConvertToDoubleQuotes());
- await computeIfNotErrorCode(
- ConvertToSingleQuotes(),
- {LintNames.prefer_single_quotes},
- );
- await computeIfNotErrorCode(
- ConvertToExpressionFunctionBody(),
- {LintNames.prefer_expression_function_bodies},
- );
- await computeIfNotErrorCode(
- ConvertToGenericFunctionSyntax(),
- {LintNames.prefer_generic_function_type_aliases},
- );
- await computeIfNotErrorCode(
- ConvertToIntLiteral(),
- {LintNames.prefer_int_literals},
- );
- await computeIfNotErrorCode(
- ConvertToListLiteral(),
- {LintNames.prefer_collection_literals},
- );
- await computeIfNotErrorCode(
- ConvertToMapLiteral(),
- {LintNames.prefer_collection_literals},
- );
- await computeIfNotErrorCode(
- ConvertToNullAware(),
- {LintNames.prefer_null_aware_operators},
- );
- await computeIfNotErrorCode(
- ConvertToPackageImport(),
- {LintNames.avoid_relative_lib_imports},
- );
- await computeIfNotErrorCode(
- ConvertToRelativeImport(),
- {LintNames.prefer_relative_imports},
- );
- await computeIfNotErrorCode(
- ConvertToSetLiteral(),
- {LintNames.prefer_collection_literals},
- );
- await compute(ExchangeOperands());
- await computeIfNotErrorCode(
- InlineInvocation(),
- {LintNames.prefer_inlined_adds},
- );
- await compute(RemoveTypeAnnotation());
- await computeIfNotErrorCode(
- ReplaceWithVar(),
- {LintNames.omit_local_variable_types},
- );
- await compute(ShadowField());
- await computeIfNotErrorCode(
- SortChildPropertyLast(),
- {LintNames.sort_child_properties_last},
- );
- await compute(SplitAndCondition());
- await computeIfNotErrorCode(
- UseCurlyBraces(),
- {LintNames.curly_braces_in_flow_control_structures},
- );
- await computeIfNotErrorCode(
- ConvertAddAllToSpread(),
- {LintNames.prefer_inlined_adds, LintNames.prefer_spread_collections},
- );
}
Future<void> _addProposal_addNotNullAssert() async {
@@ -2890,6 +2830,21 @@
_addAssistFromBuilder(changeBuilder, kind);
}
+ /// Create and return a map that can be used to look up the names of the lints
+ /// for which a given `CorrectionProducer` will be used. This allows us to
+ /// ensure that we do not also offer the change as an assist when it's already
+ /// being offered as a fix.
+ static Map<ProducerGenerator, Set<String>> createLintRuleMap() {
+ var map = <ProducerGenerator, Set<String>>{};
+ for (var entry in FixProcessor.lintProducerMap.entries) {
+ var lintName = entry.key;
+ for (var generator in entry.value) {
+ map.putIfAbsent(generator, () => <String>{}).add(lintName);
+ }
+ }
+ return map;
+ }
+
static String _replaceSourceIndent(
String source, String indentOld, String indentNew) {
return source.replaceAll(RegExp('^$indentOld', multiLine: true), indentNew);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 77859c9..98c09a1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -9,15 +9,20 @@
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/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:meta/meta.dart';
/// An object that can compute a correction (fix or assist).
@@ -31,6 +36,21 @@
/// if this producer doesn't support assists.
AssistKind get assistKind => null;
+ /// Return the type for the class `bool` from `dart:core`.
+ DartType get coreTypeBool => resolvedResult.typeProvider.boolType;
+
+ /// Return the length of the error message being fixed, or `null` if there is
+ /// no diagnostic.
+ int get errorLength => diagnostic?.problemMessage?.length;
+
+ /// Return the text of the error message being fixed, or `null` if there is
+ /// no diagnostic.
+ String get errorMessage => diagnostic?.problemMessage?.message;
+
+ /// Return the offset of the error message being fixed, or `null` if there is
+ /// no diagnostic.
+ int get errorOffset => diagnostic?.problemMessage?.offset;
+
/// Return the arguments that should be used when composing the message for a
/// fix, or `null` if the fix message has no parameters or if this producer
/// doesn't support fixes.
@@ -40,7 +60,170 @@
/// producer doesn't support fixes.
FixKind get fixKind => null;
+ /// Returns `true` if [node] is in a static context.
+ bool get inStaticContext {
+ // constructor initializer cannot reference "this"
+ if (node.thisOrAncestorOfType<ConstructorInitializer>() != null) {
+ return true;
+ }
+ // field initializer cannot reference "this"
+ if (node.thisOrAncestorOfType<FieldDeclaration>() != null) {
+ return true;
+ }
+ // static method
+ var method = node.thisOrAncestorOfType<MethodDeclaration>();
+ return method != null && method.isStatic;
+ }
+
Future<void> compute(DartChangeBuilder builder);
+
+ /// Returns an expected [DartType] of [expression], may be `null` if cannot be
+ /// inferred.
+ DartType inferUndefinedExpressionType(Expression expression) {
+ var parent = expression.parent;
+ // myFunction();
+ if (parent is ExpressionStatement) {
+ if (expression is MethodInvocation) {
+ return VoidTypeImpl.instance;
+ }
+ }
+ // return myFunction();
+ if (parent is ReturnStatement) {
+ var executable = getEnclosingExecutableElement(expression);
+ return executable?.returnType;
+ }
+ // int v = myFunction();
+ if (parent is VariableDeclaration) {
+ var variableDeclaration = parent;
+ if (variableDeclaration.initializer == expression) {
+ var variableElement = variableDeclaration.declaredElement;
+ if (variableElement != null) {
+ return variableElement.type;
+ }
+ }
+ }
+ // myField = 42;
+ if (parent is AssignmentExpression) {
+ var assignment = parent;
+ if (assignment.leftHandSide == expression) {
+ var rhs = assignment.rightHandSide;
+ if (rhs != null) {
+ return rhs.staticType;
+ }
+ }
+ }
+ // v = myFunction();
+ if (parent is AssignmentExpression) {
+ var assignment = parent;
+ if (assignment.rightHandSide == expression) {
+ if (assignment.operator.type == TokenType.EQ) {
+ // v = myFunction();
+ var lhs = assignment.leftHandSide;
+ if (lhs != null) {
+ return lhs.staticType;
+ }
+ } else {
+ // v += myFunction();
+ var method = assignment.staticElement;
+ if (method != null) {
+ var parameters = method.parameters;
+ if (parameters.length == 1) {
+ return parameters[0].type;
+ }
+ }
+ }
+ }
+ }
+ // v + myFunction();
+ if (parent is BinaryExpression) {
+ var binary = parent;
+ var method = binary.staticElement;
+ if (method != null) {
+ if (binary.rightOperand == expression) {
+ var parameters = method.parameters;
+ return parameters.length == 1 ? parameters[0].type : null;
+ }
+ }
+ }
+ // foo( myFunction() );
+ if (parent is ArgumentList) {
+ var parameter = expression.staticParameterElement;
+ return parameter?.type;
+ }
+ // bool
+ {
+ // assert( myFunction() );
+ if (parent is AssertStatement) {
+ var statement = parent;
+ if (statement.condition == expression) {
+ return coreTypeBool;
+ }
+ }
+ // if ( myFunction() ) {}
+ if (parent is IfStatement) {
+ var statement = parent;
+ if (statement.condition == expression) {
+ return coreTypeBool;
+ }
+ }
+ // while ( myFunction() ) {}
+ if (parent is WhileStatement) {
+ var statement = parent;
+ if (statement.condition == expression) {
+ return coreTypeBool;
+ }
+ }
+ // do {} while ( myFunction() );
+ if (parent is DoStatement) {
+ var statement = parent;
+ if (statement.condition == expression) {
+ return coreTypeBool;
+ }
+ }
+ // !myFunction()
+ if (parent is PrefixExpression) {
+ var prefixExpression = parent;
+ if (prefixExpression.operator.type == TokenType.BANG) {
+ return coreTypeBool;
+ }
+ }
+ // binary expression '&&' or '||'
+ if (parent is BinaryExpression) {
+ var binaryExpression = parent;
+ var operatorType = binaryExpression.operator.type;
+ if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
+ operatorType == TokenType.BAR_BAR) {
+ return coreTypeBool;
+ }
+ }
+ }
+ // we don't know
+ return null;
+ }
+
+ /// Return `true` if the [node] might be a type name.
+ bool mightBeTypeIdentifier(AstNode node) {
+ if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is TypeName) {
+ return true;
+ }
+ return _isNameOfType(node.name);
+ }
+ return false;
+ }
+
+ /// Return `true` if the [name] is capitalized.
+ bool _isNameOfType(String name) {
+ if (name.isEmpty) {
+ return false;
+ }
+ var firstLetter = name.substring(0, 1);
+ if (firstLetter.toUpperCase() != firstLetter) {
+ return false;
+ }
+ return true;
+ }
}
class CorrectionProducerContext {
@@ -145,6 +328,10 @@
Flutter get flutter => _context.flutter;
+ /// Return the library element for the library in which a correction is being
+ /// produced.
+ LibraryElement get libraryElement => resolvedResult.libraryElement;
+
AstNode get node => _context.node;
ResolvedUnitResult get resolvedResult => _context.resolvedResult;
@@ -224,3 +411,21 @@
return false;
}
}
+
+extension DartFileEditBuilderExtension on DartFileEditBuilder {
+ /// Add edits to the [builder] to remove any parentheses enclosing the
+ /// [expression].
+ // TODO(brianwilkerson) Consider moving this to DartFileEditBuilder.
+ void removeEnclosingParentheses(Expression expression) {
+ var precedence = getExpressionPrecedence(expression);
+ while (expression.parent is ParenthesizedExpression) {
+ var parenthesized = expression.parent as ParenthesizedExpression;
+ if (getExpressionParentPrecedence(parenthesized) > precedence) {
+ break;
+ }
+ addDeletion(range.token(parenthesized.leftParenthesis));
+ addDeletion(range.token(parenthesized.rightParenthesis));
+ expression = parenthesized;
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart
new file mode 100644
index 0000000..fa835e8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter_named.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/executable_parameters.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddMissingParameterNamed extends CorrectionProducer {
+ String _parameterName;
+
+ @override
+ List<Object> get fixArguments => [_parameterName];
+
+ @override
+ FixKind get fixKind => DartFixKind.ADD_MISSING_PARAMETER_NAMED;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ // Prepare the name of the missing parameter.
+ if (this.node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier node = this.node;
+ _parameterName = node.name;
+
+ // We expect that the node is part of a NamedExpression.
+ if (node.parent?.parent is! NamedExpression) {
+ return;
+ }
+ NamedExpression namedExpression = node.parent.parent;
+
+ // We should be in an ArgumentList.
+ if (namedExpression.parent is! ArgumentList) {
+ return;
+ }
+ var argumentList = namedExpression.parent;
+
+ // Prepare the invoked element.
+ var context = ExecutableParameters(sessionHelper, argumentList.parent);
+ if (context == null) {
+ return;
+ }
+
+ // We cannot add named parameters when there are positional positional.
+ if (context.optionalPositional.isNotEmpty) {
+ return;
+ }
+
+ Future<void> addParameter(int offset, String prefix, String suffix) async {
+ if (offset != null) {
+ await builder.addFileEdit(context.file, (builder) {
+ builder.addInsertion(offset, (builder) {
+ builder.write(prefix);
+ builder
+ .writeParameterMatchingArgument(namedExpression, 0, <String>{});
+ builder.write(suffix);
+ });
+ });
+ }
+ }
+
+ if (context.named.isNotEmpty) {
+ var prevNode = await context.getParameterNode(context.named.last);
+ await addParameter(prevNode?.end, ', ', '');
+ } else if (context.required.isNotEmpty) {
+ var prevNode = await context.getParameterNode(context.required.last);
+ await addParameter(prevNode?.end, ', {', '}');
+ } else {
+ var parameterList = await context.getParameterList();
+ await addParameter(parameterList?.leftParenthesis?.end, '{', '}');
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static AddMissingParameterNamed newInstance() => AddMissingParameterNamed();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
index aa108ea..21e2950 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_required_argument.dart
@@ -36,7 +36,7 @@
creation =
invocation.thisOrAncestorOfType<InstanceCreationExpression>();
if (creation != null) {
- targetElement = creation.staticElement;
+ targetElement = creation.constructorName.staticElement;
argumentList = creation.argumentList;
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart
new file mode 100644
index 0000000..b75fd4f0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_ne_null.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddNeNull extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.ADD_NE_NULL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var problemMessage = diagnostic.problemMessage;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(
+ problemMessage.offset + problemMessage.length, ' != null');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static AddNeNull newInstance() => AddNeNull();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
new file mode 100644
index 0000000..bf0ba1d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to_static_access.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ChangeToStaticAccess extends CorrectionProducer {
+ String _className;
+
+ @override
+ List<Object> get fixArguments => [_className];
+
+ @override
+ FixKind get fixKind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ Expression target;
+ Element invokedElement;
+ if (node is SimpleIdentifier && node.parent is MethodInvocation) {
+ var invocation = node.parent as MethodInvocation;
+ if (invocation.methodName == node) {
+ target = invocation.target;
+ invokedElement = invocation.methodName.staticElement;
+ }
+ } else if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) {
+ var prefixed = node.parent as PrefixedIdentifier;
+ if (prefixed.identifier == node) {
+ target = prefixed.prefix;
+ invokedElement = prefixed.identifier.staticElement;
+ }
+ }
+ if (target == null) {
+ return;
+ }
+ var declaringElement = invokedElement.enclosingElement;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(target), (DartEditBuilder builder) {
+ builder.writeReference(declaringElement);
+ });
+ });
+ _className = declaringElement.name;
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ChangeToStaticAccess newInstance() => ChangeToStaticAccess();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
index 522a60a..dcfa395 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart
@@ -29,7 +29,7 @@
if (creation == null) {
return null;
}
- var element = creation.staticElement;
+ var element = creation.constructorName.staticElement;
if (element == null ||
element.name != 'fromIterable' ||
element.enclosingElement != typeProvider.mapElement) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
index 7b4d5ba..b7ce175 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
@@ -27,7 +27,7 @@
parameters = invokeType.parameters;
}
} else if (parent is InstanceCreationExpression) {
- parameters = parent.staticElement?.parameters;
+ parameters = parent.constructorName.staticElement?.parameters;
} else if (parent is MethodInvocation) {
var invokeType = parent.staticInvokeType;
if (invokeType is FunctionType) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
new file mode 100644
index 0000000..0a91c00
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class CreateClass extends CorrectionProducer {
+ String className;
+
+ @override
+ List<Object> get fixArguments => [className];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_CLASS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ Element prefixElement;
+ SimpleIdentifier nameNode;
+ ArgumentList arguments;
+ if (node is Annotation) {
+ var annotation = node as Annotation;
+ var name = annotation.name;
+ arguments = annotation.arguments;
+ if (name == null || name.staticElement != null || arguments == null) {
+ // TODO(brianwilkerson) Consider supporting creating a class when the
+ // arguments are missing by also adding an empty argument list.
+ return;
+ }
+ node = name;
+ }
+ if (node is SimpleIdentifier) {
+ nameNode = node;
+ } else if (node is PrefixedIdentifier) {
+ prefixElement = node.prefix.staticElement;
+ if (prefixElement == null) {
+ return;
+ }
+ nameNode = node.identifier;
+ } else {
+ return;
+ }
+ if (!mightBeTypeIdentifier(nameNode)) {
+ return;
+ }
+ className = nameNode.name;
+ // prepare environment
+ Element targetUnit;
+ var prefix = '';
+ var suffix = '';
+ var offset = -1;
+ String filePath;
+ if (prefixElement == null) {
+ targetUnit = unit.declaredElement;
+ var enclosingMember = node.thisOrAncestorMatching((node) =>
+ node is CompilationUnitMember && node.parent is CompilationUnit);
+ if (enclosingMember == null) {
+ return;
+ }
+ offset = enclosingMember.end;
+ filePath = file;
+ prefix = '$eol$eol';
+ } else {
+ for (var import in libraryElement.imports) {
+ if (prefixElement is PrefixElement && import.prefix == prefixElement) {
+ var library = import.importedLibrary;
+ if (library != null) {
+ targetUnit = library.definingCompilationUnit;
+ var targetSource = targetUnit.source;
+ try {
+ offset = targetSource.contents.data.length;
+ filePath = targetSource.fullName;
+ prefix = '$eol';
+ suffix = '$eol';
+ } on FileSystemException {
+ // If we can't read the file to get the offset, then we can't
+ // create a fix.
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (offset < 0) {
+ return;
+ }
+ await builder.addFileEdit(filePath, (DartFileEditBuilder builder) {
+ builder.addInsertion(offset, (DartEditBuilder builder) {
+ builder.write(prefix);
+ if (arguments == null) {
+ builder.writeClassDeclaration(className, nameGroupName: 'NAME');
+ } else {
+ builder.writeClassDeclaration(className, nameGroupName: 'NAME',
+ membersWriter: () {
+ builder.write(' ');
+ builder.writeConstructorDeclaration(className,
+ argumentList: arguments,
+ classNameGroupName: 'NAME',
+ isConst: true);
+ builder.writeln();
+ });
+ }
+ builder.write(suffix);
+ });
+ if (prefixElement == null) {
+ builder.addLinkedPosition(range.node(node), 'NAME');
+ }
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateClass newInstance() => CreateClass();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
new file mode 100644
index 0000000..56e71e2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateConstructorForFinalFields extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS;
+
+ bool get _isNonNullable => unit.featureSet.isEnabled(Feature.non_nullable);
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) {
+ return;
+ }
+
+ var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
+ if (classDeclaration == null) {
+ return;
+ }
+ var className = classDeclaration.name.name;
+ var superType = classDeclaration.declaredElement.supertype;
+
+ // prepare names of uninitialized final fields
+ var fieldNames = <String>[];
+ for (var member in classDeclaration.members) {
+ if (member is FieldDeclaration) {
+ var variableList = member.fields;
+ if (variableList.isFinal) {
+ fieldNames.addAll(variableList.variables
+ .where((v) => v.initializer == null)
+ .map((v) => v.name.name));
+ }
+ }
+ }
+ // prepare location for a new constructor
+ var targetLocation = utils.prepareNewConstructorLocation(classDeclaration);
+
+ if (flutter.isExactlyStatelessWidgetType(superType) ||
+ flutter.isExactlyStatefulWidgetType(superType)) {
+ // Specialize for Flutter widgets.
+ var keyClass = await sessionHelper.getClass(flutter.widgetsUri, 'Key');
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+ builder.write(targetLocation.prefix);
+ builder.write('const ');
+ builder.write(className);
+ builder.write('({');
+ builder.writeType(
+ keyClass.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: _isNonNullable
+ ? NullabilitySuffix.question
+ : NullabilitySuffix.star,
+ ),
+ );
+ builder.write(' key');
+
+ var childrenFields = <String>[];
+ for (var fieldName in fieldNames) {
+ if (fieldName == 'child' || fieldName == 'children') {
+ childrenFields.add(fieldName);
+ continue;
+ }
+ builder.write(', this.');
+ builder.write(fieldName);
+ }
+ for (var fieldName in childrenFields) {
+ builder.write(', this.');
+ builder.write(fieldName);
+ }
+
+ builder.write('}) : super(key: key);');
+ builder.write(targetLocation.suffix);
+ });
+ });
+ } else {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+ builder.write(targetLocation.prefix);
+ builder.writeConstructorDeclaration(className,
+ fieldNames: fieldNames);
+ builder.write(targetLocation.suffix);
+ });
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateConstructorForFinalFields newInstance() =>
+ CreateConstructorForFinalFields();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
new file mode 100644
index 0000000..d3365c6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateGetter extends CorrectionProducer {
+ String getterName;
+
+ @override
+ List<Object> get fixArguments => [getterName];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_GETTER;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier nameNode = node;
+ getterName = nameNode.name;
+ if (!nameNode.inGetterContext()) {
+ return;
+ }
+ // prepare target
+ Expression target;
+ {
+ var nameParent = nameNode.parent;
+ if (nameParent is PrefixedIdentifier) {
+ target = nameParent.prefix;
+ } else if (nameParent is PropertyAccess) {
+ target = nameParent.realTarget;
+ }
+ }
+ // prepare target element
+ var staticModifier = false;
+ Element targetElement;
+ if (target is ExtensionOverride) {
+ targetElement = target.staticElement;
+ } else if (target is Identifier &&
+ target.staticElement is ExtensionElement) {
+ targetElement = target.staticElement;
+ staticModifier = true;
+ } else if (target != null) {
+ // prepare target interface type
+ var targetType = target.staticType;
+ if (targetType is! InterfaceType) {
+ return;
+ }
+ targetElement = targetType.element;
+ // maybe static
+ if (target is Identifier) {
+ var targetIdentifier = target;
+ var targetElement = targetIdentifier.staticElement;
+ staticModifier = targetElement?.kind == ElementKind.CLASS;
+ }
+ } else {
+ targetElement =
+ getEnclosingClassElement(node) ?? getEnclosingExtensionElement(node);
+ if (targetElement == null) {
+ return;
+ }
+ staticModifier = inStaticContext;
+ }
+ if (targetElement.librarySource.isInSystemLibrary) {
+ return;
+ }
+ // prepare target declaration
+ var targetDeclarationResult =
+ await sessionHelper.getElementDeclaration(targetElement);
+ if (targetDeclarationResult == null) {
+ return;
+ }
+ if (targetDeclarationResult.node is! ClassOrMixinDeclaration &&
+ targetDeclarationResult.node is! ExtensionDeclaration) {
+ return;
+ }
+ CompilationUnitMember targetNode = targetDeclarationResult.node;
+ // prepare location
+ var targetLocation = CorrectionUtils(targetDeclarationResult.resolvedUnit)
+ .prepareNewGetterLocation(targetNode);
+ // build method source
+ var targetSource = targetElement.source;
+ var targetFile = targetSource.fullName;
+ await builder.addFileEdit(targetFile, (DartFileEditBuilder builder) {
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+ var fieldTypeNode = climbPropertyAccess(nameNode);
+ var fieldType = inferUndefinedExpressionType(fieldTypeNode);
+ builder.write(targetLocation.prefix);
+ builder.writeGetterDeclaration(getterName,
+ isStatic: staticModifier,
+ nameGroupName: 'NAME',
+ returnType: fieldType,
+ returnTypeGroupName: 'TYPE');
+ builder.write(targetLocation.suffix);
+ });
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateGetter newInstance() => CreateGetter();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart
new file mode 100644
index 0000000..5528f79
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_local_variable.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class CreateLocalVariable extends CorrectionProducer {
+ String variableName;
+
+ @override
+ List<Object> get fixArguments => [variableName];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_LOCAL_VARIABLE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier nameNode = node;
+ variableName = nameNode.name;
+ // if variable is assigned, convert assignment into declaration
+ if (node.parent is AssignmentExpression) {
+ AssignmentExpression assignment = node.parent;
+ if (assignment.leftHandSide == node &&
+ assignment.operator.type == TokenType.EQ &&
+ assignment.parent is ExpressionStatement) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(node.offset, 'var ');
+ });
+ return;
+ }
+ }
+ // prepare target Statement
+ var target = node.thisOrAncestorOfType<Statement>();
+ if (target == null) {
+ return;
+ }
+ var prefix = utils.getNodePrefix(target);
+ // compute type
+ var type = inferUndefinedExpressionType(node);
+ if (!(type == null || type is InterfaceType || type is FunctionType)) {
+ return;
+ }
+ // build variable declaration source
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(target.offset, (DartEditBuilder builder) {
+ builder.writeLocalVariableDeclaration(variableName,
+ nameGroupName: 'NAME', type: type, typeGroupName: 'TYPE');
+ builder.write(eol);
+ builder.write(prefix);
+ });
+ builder.addLinkedPosition(range.node(node), 'NAME');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateLocalVariable newInstance() => CreateLocalVariable();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
new file mode 100644
index 0000000..b5f45d2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_missing_overrides.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/utilities/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/error/inheritance_override.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show Position;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateMissingOverrides extends CorrectionProducer {
+ int numElements;
+
+ @override
+ List<Object> get fixArguments => [numElements];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_MISSING_OVERRIDES;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node.parent is! ClassDeclaration) {
+ return;
+ }
+ var targetClass = node.parent as ClassDeclaration;
+ var targetClassElement = targetClass.declaredElement;
+ utils.targetClassElement = targetClassElement;
+ var signatures =
+ InheritanceOverrideVerifier.missingOverrides(targetClass).toList();
+ // sort by name, getters before setters
+ signatures.sort((ExecutableElement a, ExecutableElement b) {
+ var names = compareStrings(a.displayName, b.displayName);
+ if (names != 0) {
+ return names;
+ }
+ if (a.kind == ElementKind.GETTER) {
+ return -1;
+ }
+ return 1;
+ });
+ numElements = signatures.length;
+
+ var location =
+ utils.prepareNewClassMemberLocation(targetClass, (_) => true);
+
+ var prefix = utils.getIndent(1);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(location.offset, (DartEditBuilder builder) {
+ // Separator management.
+ var numOfMembersWritten = 0;
+ void addSeparatorBetweenDeclarations() {
+ if (numOfMembersWritten == 0) {
+ builder.write(location.prefix);
+ } else {
+ builder.write(eol); // after the previous member
+ builder.write(eol); // empty line separator
+ builder.write(prefix);
+ }
+ numOfMembersWritten++;
+ }
+
+ // merge getter/setter pairs into fields
+ for (var i = 0; i < signatures.length; i++) {
+ var element = signatures[i];
+ if (element.kind == ElementKind.GETTER && i + 1 < signatures.length) {
+ var nextElement = signatures[i + 1];
+ if (nextElement.kind == ElementKind.SETTER) {
+ // remove this and the next elements, adjust iterator
+ signatures.removeAt(i + 1);
+ signatures.removeAt(i);
+ i--;
+ numElements--;
+ // separator
+ addSeparatorBetweenDeclarations();
+ // @override
+ builder.write('@override');
+ builder.write(eol);
+ // add field
+ builder.write(prefix);
+ builder.writeType(element.returnType, required: true);
+ builder.write(' ');
+ builder.write(element.name);
+ builder.write(';');
+ }
+ }
+ }
+ // add elements
+ for (var element in signatures) {
+ addSeparatorBetweenDeclarations();
+ builder.writeOverride(element);
+ }
+ builder.write(location.suffix);
+ });
+ });
+ builder.setSelection(Position(file, location.offset));
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateMissingOverrides newInstance() => CreateMissingOverrides();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
new file mode 100644
index 0000000..370e086
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_mixin.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class CreateMixin extends CorrectionProducer {
+ String mixinName;
+
+ @override
+ List<Object> get fixArguments => [mixinName];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_MIXIN;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ Element prefixElement;
+ SimpleIdentifier nameNode;
+ if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is TypeName &&
+ parent.parent is ConstructorName &&
+ parent.parent.parent is InstanceCreationExpression) {
+ return;
+ } else {
+ nameNode = node;
+ mixinName = nameNode.name;
+ }
+ } else if (node is PrefixedIdentifier) {
+ if (node.parent is InstanceCreationExpression) {
+ return;
+ }
+ PrefixedIdentifier prefixedIdentifier = node;
+ prefixElement = prefixedIdentifier.prefix.staticElement;
+ if (prefixElement == null) {
+ return;
+ }
+ nameNode = prefixedIdentifier.identifier;
+ mixinName = prefixedIdentifier.identifier.name;
+ } else {
+ return;
+ }
+ if (!mightBeTypeIdentifier(nameNode)) {
+ return;
+ }
+ // prepare environment
+ Element targetUnit;
+ var prefix = '';
+ var suffix = '';
+ var offset = -1;
+ String filePath;
+ if (prefixElement == null) {
+ targetUnit = unit.declaredElement;
+ var enclosingMember = node.thisOrAncestorMatching((node) =>
+ node is CompilationUnitMember && node.parent is CompilationUnit);
+ if (enclosingMember == null) {
+ return;
+ }
+ offset = enclosingMember.end;
+ filePath = file;
+ prefix = '$eol$eol';
+ } else {
+ for (var import in libraryElement.imports) {
+ if (prefixElement is PrefixElement && import.prefix == prefixElement) {
+ var library = import.importedLibrary;
+ if (library != null) {
+ targetUnit = library.definingCompilationUnit;
+ var targetSource = targetUnit.source;
+ try {
+ offset = targetSource.contents.data.length;
+ filePath = targetSource.fullName;
+ prefix = '$eol';
+ suffix = '$eol';
+ } on FileSystemException {
+ // If we can't read the file to get the offset, then we can't
+ // create a fix.
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (offset < 0) {
+ return;
+ }
+ await builder.addFileEdit(filePath, (DartFileEditBuilder builder) {
+ builder.addInsertion(offset, (DartEditBuilder builder) {
+ builder.write(prefix);
+ builder.writeMixinDeclaration(mixinName, nameGroupName: 'NAME');
+ builder.write(suffix);
+ });
+ if (prefixElement == null) {
+ builder.addLinkedPosition(range.node(node), 'NAME');
+ }
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateMixin newInstance() => CreateMixin();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
new file mode 100644
index 0000000..53174e0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_no_such_method.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateNoSuchMethod extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_NO_SUCH_METHOD;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node.parent is! ClassDeclaration) {
+ return;
+ }
+ var targetClass = node.parent as ClassDeclaration;
+ // prepare environment
+ var prefix = utils.getIndent(1);
+ var insertOffset = targetClass.end - 1;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addInsertion(insertOffset, (DartEditBuilder builder) {
+ builder.selectHere();
+ // insert empty line before existing member
+ if (targetClass.members.isNotEmpty) {
+ builder.write(eol);
+ }
+ // append method
+ builder.write(prefix);
+ builder.write(
+ 'noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);');
+ builder.write(eol);
+ });
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateNoSuchMethod newInstance() => CreateNoSuchMethod();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
new file mode 100644
index 0000000..e7ddc3d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_setter.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class CreateSetter extends CorrectionProducer {
+ String setterName;
+
+ @override
+ List<Object> get fixArguments => [setterName];
+
+ @override
+ FixKind get fixKind => DartFixKind.CREATE_SETTER;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier nameNode = node;
+ if (!nameNode.inSetterContext()) {
+ return;
+ }
+ // prepare target
+ Expression target;
+ {
+ var nameParent = nameNode.parent;
+ if (nameParent is PrefixedIdentifier) {
+ target = nameParent.prefix;
+ } else if (nameParent is PropertyAccess) {
+ target = nameParent.realTarget;
+ }
+ }
+ // prepare target element
+ var staticModifier = false;
+ Element targetElement;
+ if (target is ExtensionOverride) {
+ targetElement = target.staticElement;
+ } else if (target is Identifier &&
+ target.staticElement is ExtensionElement) {
+ targetElement = target.staticElement;
+ staticModifier = true;
+ } else if (target != null) {
+ // prepare target interface type
+ var targetType = target.staticType;
+ if (targetType is! InterfaceType) {
+ return;
+ }
+ targetElement = targetType.element;
+ // maybe static
+ if (target is Identifier) {
+ var targetIdentifier = target;
+ var targetElement = targetIdentifier.staticElement;
+ staticModifier = targetElement?.kind == ElementKind.CLASS;
+ }
+ } else {
+ targetElement =
+ getEnclosingClassElement(node) ?? getEnclosingExtensionElement(node);
+ if (targetElement == null) {
+ return;
+ }
+ staticModifier = inStaticContext;
+ }
+ if (targetElement.librarySource.isInSystemLibrary) {
+ return;
+ }
+ // prepare target declaration
+ var targetDeclarationResult =
+ await sessionHelper.getElementDeclaration(targetElement);
+ if (targetDeclarationResult == null) {
+ return;
+ }
+ if (targetDeclarationResult.node is! ClassOrMixinDeclaration &&
+ targetDeclarationResult.node is! ExtensionDeclaration) {
+ return;
+ }
+ CompilationUnitMember targetNode = targetDeclarationResult.node;
+ // prepare location
+ var targetLocation = CorrectionUtils(targetDeclarationResult.resolvedUnit)
+ .prepareNewGetterLocation(targetNode); // Rename to "AccessorLocation"
+ // build method source
+ var targetSource = targetElement.source;
+ var targetFile = targetSource.fullName;
+ setterName = nameNode.name;
+ await builder.addFileEdit(targetFile, (DartFileEditBuilder builder) {
+ builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+ var parameterTypeNode = climbPropertyAccess(nameNode);
+ var parameterType = inferUndefinedExpressionType(parameterTypeNode);
+ builder.write(targetLocation.prefix);
+ builder.writeSetterDeclaration(setterName,
+ isStatic: staticModifier,
+ nameGroupName: 'NAME',
+ parameterType: parameterType,
+ parameterTypeGroupName: 'TYPE');
+ builder.write(targetLocation.suffix);
+ });
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static CreateSetter newInstance() => CreateSetter();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart b/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart
index c04eceb..7c6a269 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/exchange_operands.dart
@@ -63,4 +63,7 @@
}
});
}
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ExchangeOperands newInstance() => ExchangeOperands();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
new file mode 100644
index 0000000..cc3c82c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/extend_class_for_mixin.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ExtendClassForMixin extends CorrectionProducer {
+ String typeName;
+
+ @override
+ List<Object> get fixArguments => [typeName];
+
+ @override
+ FixKind get fixKind => DartFixKind.EXTEND_CLASS_FOR_MIXIN;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var declaration = node.thisOrAncestorOfType<ClassDeclaration>();
+ if (declaration != null && declaration.extendsClause == null) {
+ // TODO(brianwilkerson) Find a way to pass in the name of the class
+ // without needing to parse the message.
+ var message = diagnostic.problemMessage.message;
+ var endIndex = message.lastIndexOf("'");
+ var startIndex = message.lastIndexOf("'", endIndex - 1) + 1;
+ typeName = message.substring(startIndex, endIndex);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(
+ declaration.typeParameters?.end ?? declaration.name.end,
+ ' extends $typeName');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ExtendClassForMixin newInstance() => ExtendClassForMixin();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart b/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart
new file mode 100644
index 0000000..caa2555
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/insert_semicolon.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class InsertSemicolon extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.INSERT_SEMICOLON;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var message = diagnostic.problemMessage;
+ if (message.message.contains("';'")) {
+ if (_isAwaitNode()) {
+ return;
+ }
+ var insertOffset = message.offset + message.length;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(insertOffset, ';');
+ });
+ }
+ }
+
+ bool _isAwaitNode() {
+ var node = this.node;
+ return node is SimpleIdentifier && node.name == 'await';
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static InsertSemicolon newInstance() => InsertSemicolon();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
new file mode 100644
index 0000000..21ef3b5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_class_abstract.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class MakeClassAbstract extends CorrectionProducer {
+ String className;
+
+ @override
+ List<Object> get fixArguments => [className];
+
+ @override
+ FixKind get fixKind => DartFixKind.MAKE_CLASS_ABSTRACT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var enclosingClass = node.thisOrAncestorOfType<ClassDeclaration>();
+ if (enclosingClass == null) {
+ return;
+ }
+ className = enclosingClass.name.name;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(
+ enclosingClass.classKeyword.offset, 'abstract ');
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static MakeClassAbstract newInstance() => MakeClassAbstract();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
new file mode 100644
index 0000000..7ea72f1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_field_not_final.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class MakeFieldNotFinal extends CorrectionProducer {
+ String fieldName;
+
+ @override
+ List<Object> get fixArguments => [fieldName];
+
+ @override
+ FixKind get fixKind => DartFixKind.MAKE_FIELD_NOT_FINAL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is SimpleIdentifier &&
+ node.staticElement is PropertyAccessorElement) {
+ PropertyAccessorElement getter = node.staticElement;
+ if (getter.isGetter &&
+ getter.isSynthetic &&
+ !getter.variable.isSynthetic &&
+ getter.variable.setter == null &&
+ getter.enclosingElement is ClassElement) {
+ var declarationResult =
+ await sessionHelper.getElementDeclaration(getter.variable);
+ var variable = declarationResult.node;
+ if (variable is VariableDeclaration &&
+ variable.parent is VariableDeclarationList &&
+ variable.parent.parent is FieldDeclaration) {
+ VariableDeclarationList declarationList = variable.parent;
+ var keywordToken = declarationList.keyword;
+ if (declarationList.variables.length == 1 &&
+ keywordToken.keyword == Keyword.FINAL) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (declarationList.type != null) {
+ builder.addReplacement(
+ range.startStart(keywordToken, declarationList.type),
+ (DartEditBuilder builder) {});
+ } else {
+ builder.addReplacement(range.startStart(keywordToken, variable),
+ (DartEditBuilder builder) {
+ builder.write('var ');
+ });
+ }
+ });
+ fieldName = getter.variable.displayName;
+ }
+ }
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static MakeFieldNotFinal newInstance() => MakeFieldNotFinal();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
new file mode 100644
index 0000000..7679185
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_variable_not_final.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class MakeVariableNotFinal extends CorrectionProducer {
+ String _variableName;
+
+ @override
+ List<Object> get fixArguments => [_variableName];
+
+ @override
+ FixKind get fixKind => DartFixKind.MAKE_VARIABLE_NOT_FINAL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var node = this.node;
+ if (node is SimpleIdentifier &&
+ node.staticElement is LocalVariableElement) {
+ LocalVariableElement variable = node.staticElement;
+ var id = NodeLocator(variable.nameOffset).searchWithin(unit);
+ var decl = id?.parent;
+ if (decl is VariableDeclaration &&
+ decl.parent is VariableDeclarationList) {
+ VariableDeclarationList declarationList = decl.parent;
+ var keywordToken = declarationList.keyword;
+ if (declarationList.variables.length == 1 &&
+ keywordToken.keyword == Keyword.FINAL) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (declarationList.type != null) {
+ builder.addDeletion(
+ range.startStart(keywordToken, declarationList.type));
+ } else {
+ builder.addSimpleReplacement(range.token(keywordToken), 'var');
+ }
+ });
+ declarationList.variables[0].name.name;
+ _variableName = declarationList.variables[0].name.name;
+ }
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static MakeVariableNotFinal newInstance() => MakeVariableNotFinal();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
new file mode 100644
index 0000000..05a35e3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class MoveTypeArgumentsToClass extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is TypeArgumentList) {
+ TypeArgumentList typeArguments = coveredNode;
+ if (typeArguments.parent is! InstanceCreationExpression) {
+ return;
+ }
+ InstanceCreationExpression creation = typeArguments.parent;
+ var typeName = creation.constructorName.type;
+ if (typeName.typeArguments != null) {
+ return;
+ }
+ var element = typeName.type.element;
+ if (element is ClassElement &&
+ element.typeParameters != null &&
+ element.typeParameters.length == typeArguments.arguments.length) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var argumentText = utils.getNodeText(typeArguments);
+ builder.addSimpleInsertion(typeName.end, argumentText);
+ builder.addDeletion(range.node(typeArguments));
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static MoveTypeArgumentsToClass newInstance() => MoveTypeArgumentsToClass();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
new file mode 100644
index 0000000..5cb54ce
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/qualify_reference.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class QualifyReference extends CorrectionProducer {
+ String _qualifiedName;
+
+ @override
+ List<Object> get fixArguments => [_qualifiedName];
+
+ @override
+ FixKind get fixKind => DartFixKind.QUALIFY_REFERENCE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier memberName = node;
+ var parent = node.parent;
+ AstNode target;
+ if (parent is MethodInvocation && node == parent.methodName) {
+ target = parent.target;
+ } else if (parent is PropertyAccess && node == parent.propertyName) {
+ target = parent.target;
+ }
+ if (target != null) {
+ return;
+ }
+ var enclosingElement = memberName.staticElement.enclosingElement;
+ if (enclosingElement.library != libraryElement) {
+ // TODO(brianwilkerson) Support qualifying references to members defined
+ // in other libraries. `DartEditBuilder` currently defines the method
+ // `writeType`, which is close, but we also need to handle extensions,
+ // which don't have a type.
+ return;
+ }
+ var containerName = enclosingElement.name;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(node.offset, '$containerName.');
+ });
+ _qualifiedName = '$containerName.${memberName.name}';
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static QualifyReference newInstance() => QualifyReference();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
new file mode 100644
index 0000000..c6e79ef
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_annotation.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveAnnotation extends CorrectionProducer {
+ String _annotationName;
+
+ @override
+ List<Object> get fixArguments => [_annotationName];
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_ANNOTATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ void addFix(Annotation node) async {
+ if (node == null) {
+ return;
+ }
+ var followingToken = node.endToken.next;
+ followingToken = followingToken.precedingComments ?? followingToken;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(node, followingToken));
+ });
+ _annotationName = node.name.name;
+ }
+
+ Annotation findAnnotation(
+ NodeList<Annotation> metadata, String targetName) {
+ return metadata.firstWhere(
+ (annotation) => annotation.name.name == targetName,
+ orElse: () => null);
+ }
+
+ var node = coveredNode;
+ if (node is Annotation) {
+ await addFix(node);
+ } else if (node is DefaultFormalParameter) {
+ await addFix(findAnnotation(node.parameter.metadata, 'required'));
+ } else if (node is NormalFormalParameter) {
+ await addFix(findAnnotation(node.metadata, 'required'));
+ } else if (node is DeclaredSimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is MethodDeclaration) {
+ await addFix(findAnnotation(parent.metadata, 'override'));
+ } else if (parent is VariableDeclaration) {
+ var fieldDeclaration = parent.thisOrAncestorOfType<FieldDeclaration>();
+ if (fieldDeclaration != null) {
+ await addFix(findAnnotation(fieldDeclaration.metadata, 'override'));
+ }
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveAnnotation newInstance() => RemoveAnnotation();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
new file mode 100644
index 0000000..94cc3a2
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_dead_code.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveDeadCode extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_DEAD_CODE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var coveringNode = coveredNode;
+ if (coveringNode is Expression) {
+ var parent = coveredNode.parent;
+ if (parent is BinaryExpression) {
+ if (parent.rightOperand == coveredNode) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.endEnd(parent.leftOperand, coveredNode));
+ });
+ }
+ }
+ } else if (coveringNode is Block) {
+ var block = coveringNode;
+ var statementsToRemove = <Statement>[];
+ var problemMessage = diagnostic.problemMessage;
+ var errorRange =
+ SourceRange(problemMessage.offset, problemMessage.length);
+ for (var statement in block.statements) {
+ if (range.node(statement).intersects(errorRange)) {
+ statementsToRemove.add(statement);
+ }
+ }
+ if (statementsToRemove.isNotEmpty) {
+ var rangeToRemove = utils.getLinesRangeStatements(statementsToRemove);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(rangeToRemove);
+ });
+ }
+ } else if (coveringNode is Statement) {
+ var rangeToRemove =
+ utils.getLinesRangeStatements(<Statement>[coveringNode]);
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(rangeToRemove);
+ });
+ } else if (coveringNode is CatchClause) {
+ TryStatement tryStatement = coveringNode.parent;
+ var catchClauses = tryStatement.catchClauses;
+ var index = catchClauses.indexOf(coveringNode);
+ var previous = index == 0 ? tryStatement.body : catchClauses[index - 1];
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.endEnd(previous, coveringNode));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveDeadCode newInstance() => RemoveDeadCode();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
new file mode 100644
index 0000000..0b44db3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_name_from_combinator.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveNameFromCombinator extends CorrectionProducer {
+ String _combinatorKind;
+
+ @override
+ List<Object> get fixArguments => [_combinatorKind];
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_NAME_FROM_COMBINATOR;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ SourceRange rangeForCombinator(Combinator combinator) {
+ var parent = combinator.parent;
+ if (parent is NamespaceDirective) {
+ var combinators = parent.combinators;
+ if (combinators.length == 1) {
+ var previousToken =
+ combinator.parent.findPrevious(combinator.beginToken);
+ if (previousToken != null) {
+ return range.endEnd(previousToken, combinator);
+ }
+ return null;
+ }
+ var index = combinators.indexOf(combinator);
+ if (index < 0) {
+ return null;
+ } else if (index == combinators.length - 1) {
+ return range.endEnd(combinators[index - 1], combinator);
+ }
+ return range.startStart(combinator, combinators[index + 1]);
+ }
+ return null;
+ }
+
+ SourceRange rangeForNameInCombinator(
+ Combinator combinator, SimpleIdentifier name) {
+ NodeList<SimpleIdentifier> names;
+ if (combinator is HideCombinator) {
+ names = combinator.hiddenNames;
+ } else if (combinator is ShowCombinator) {
+ names = combinator.shownNames;
+ } else {
+ return null;
+ }
+ if (names.length == 1) {
+ return rangeForCombinator(combinator);
+ }
+ var index = names.indexOf(name);
+ if (index < 0) {
+ return null;
+ } else if (index == names.length - 1) {
+ return range.endEnd(names[index - 1], name);
+ }
+ return range.startStart(name, names[index + 1]);
+ }
+
+ var node = coveredNode;
+ if (node is SimpleIdentifier) {
+ var parent = coveredNode.parent;
+ if (parent is Combinator) {
+ var rangeToRemove = rangeForNameInCombinator(parent, node);
+ if (rangeToRemove == null) {
+ return;
+ }
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(rangeToRemove);
+ });
+ _combinatorKind = parent is HideCombinator ? 'hide' : 'show';
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveNameFromCombinator newInstance() => RemoveNameFromCombinator();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
new file mode 100644
index 0000000..8112a2e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_parameters_in_getter_declaration.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveParametersInGetterDeclaration extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is MethodDeclaration) {
+ // Support for the analyzer error.
+ var method = node as MethodDeclaration;
+ var name = method.name;
+ var body = method.body;
+ if (name != null && body != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(range.endStart(name, body), ' ');
+ });
+ }
+ } else if (node is FormalParameterList) {
+ // Support for the fasta error.
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.node(node));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveParametersInGetterDeclaration newInstance() =>
+ RemoveParametersInGetterDeclaration();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart
new file mode 100644
index 0000000..20ec8de
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveParenthesesInGetterInvocation extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ var invocation = coveredNode?.parent;
+ if (invocation is FunctionExpressionInvocation) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.node(invocation.argumentList));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveParenthesesInGetterInvocation newInstance() =>
+ RemoveParenthesesInGetterInvocation();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
index 923891d..aa4f045 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_annotation.dart
@@ -20,24 +20,19 @@
@override
Future<void> compute(DartChangeBuilder builder) async {
- var parameter = node.thisOrAncestorOfType<FormalParameter>();
- if (parameter is SimpleFormalParameter) {
- var type = parameter.type;
- if (type != null) {
- return _removeTypeAnnotation(builder, type);
+ for (var node = this.node; node != null; node = node.parent) {
+ if (node is DeclaredIdentifier) {
+ return _removeFromDeclaredIdentifier(builder, node);
}
- }
- var declarationList = node.thisOrAncestorOfType<VariableDeclarationList>();
- if (declarationList != null) {
- return _removeFromDeclarationList(builder, declarationList);
- }
- var declaredIdentifier = node.thisOrAncestorOfType<DeclaredIdentifier>();
- if (declaredIdentifier != null) {
- return _removeFromDeclaredIdentifier(builder, declaredIdentifier);
- }
- var type = node.thisOrAncestorOfType<TypeAnnotation>();
- if (type != null) {
- return _removeTypeAnnotation(builder, type);
+ if (node is SimpleFormalParameter) {
+ return _removeTypeAnnotation(builder, node.type);
+ }
+ if (node is TypeAnnotation && diagnostic != null) {
+ return _removeTypeAnnotation(builder, node);
+ }
+ if (node is VariableDeclarationList) {
+ return _removeFromDeclarationList(builder, node);
+ }
}
}
@@ -94,6 +89,10 @@
Future<void> _removeTypeAnnotation(
DartChangeBuilder builder, TypeAnnotation type) async {
+ if (type == null) {
+ return;
+ }
+
await builder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addDeletion(range.startStart(type, type.endToken.next));
});
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart
new file mode 100644
index 0000000..e47e502
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_type_arguments.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveTypeArguments extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_TYPE_ARGUMENTS;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is TypeArgumentList) {
+ TypeArgumentList typeArguments = coveredNode;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.node(typeArguments));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveTypeArguments newInstance() => RemoveTypeArguments();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart
new file mode 100644
index 0000000..c3a26c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_cast.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnnecessaryCast extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_CAST;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is! AsExpression) {
+ return;
+ }
+ var asExpression = coveredNode as AsExpression;
+ var expression = asExpression.expression;
+ // remove 'as T' from 'e as T'
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.endEnd(expression, asExpression));
+ builder.removeEnclosingParentheses(asExpression);
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnnecessaryCast newInstance() => RemoveUnnecessaryCast();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
new file mode 100644
index 0000000..f783e62
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_clause.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedCatchClause extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is SimpleIdentifier) {
+ var catchClause = node.parent;
+ if (catchClause is CatchClause &&
+ catchClause.exceptionParameter == node) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(
+ range.startStart(catchClause.catchKeyword, catchClause.body));
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnusedCatchClause newInstance() => RemoveUnusedCatchClause();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
new file mode 100644
index 0000000..0f43ef3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_catch_stack.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedCatchStack extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is SimpleIdentifier) {
+ var catchClause = node.parent;
+ if (catchClause is CatchClause &&
+ catchClause.stackTraceParameter == node &&
+ catchClause.exceptionParameter != null) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder
+ .addDeletion(range.endEnd(catchClause.exceptionParameter, node));
+ });
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnusedCatchStack newInstance() => RemoveUnusedCatchStack();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
new file mode 100644
index 0000000..7a007a9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_import.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedImport extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_IMPORT;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ // prepare ImportDirective
+ var importDirective = node.thisOrAncestorOfType<ImportDirective>();
+ if (importDirective == null) {
+ return;
+ }
+ // remove the whole line with import
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(utils.getLinesRange(range.node(importDirective)));
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnusedImport newInstance() => RemoveUnusedImport();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
new file mode 100644
index 0000000..69675fd
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_label.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedLabel extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_LABEL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is Label) {
+ var nextToken = node.endToken.next;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(node, nextToken));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnusedLabel newInstance() => RemoveUnusedLabel();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart
new file mode 100644
index 0000000..15cab104
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unused_parameter.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnusedParameter extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNUSED_PARAMETER;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is FormalParameter) {
+ var parameter = node as FormalParameter;
+ var parameterList = parameter.parent as FormalParameterList;
+ var parameters = parameterList.parameters;
+ var index = parameters.indexOf(parameter);
+ await builder.addFileEdit(file, (builder) {
+ if (index == 0) {
+ // Remove the first parameter in the list.
+ if (parameters.length == 1) {
+ // There is only one parameter. By removing everything inside the
+ // parentheses we also remove any square brackets or curly braces.
+ builder.addDeletion(range.endStart(
+ parameterList.leftParenthesis, parameterList.rightParenthesis));
+ } else {
+ var following = parameters[1];
+ if (parameter.isRequiredPositional &&
+ !following.isRequiredPositional) {
+ // The parameter to be removed and the following parameter are not
+ // of the same kind, so there is a delimiter between them that we
+ // can't delete.
+ builder.addDeletion(
+ range.startStart(parameter, parameterList.leftDelimiter));
+ } else {
+ // The parameter to be removed and the following parameter are of
+ // the same kind, so there is no delimiter between them.
+ builder.addDeletion(range.startStart(parameter, following));
+ }
+ }
+ } else {
+ var preceding = parameters[index - 1];
+ if (preceding.isRequiredPositional &&
+ !parameter.isRequiredPositional) {
+ // The parameter to be removed and the preceding parameter are not
+ // of the same kind, so there is a delimiter between them.
+ if (index == parameters.length - 1) {
+ // The parameter to be removed is the only parameter between the
+ // delimiters, so remove the delimiters with the parameter.
+ var trailingToken = parameterList.rightParenthesis;
+ if (trailingToken.previous.type == TokenType.COMMA) {
+ // Leave the trailing comma if there is one.
+ trailingToken = trailingToken.previous;
+ }
+ builder.addDeletion(range.endStart(preceding, trailingToken));
+ } else {
+ // The parameter to be removed is the first inside the delimiters
+ // but the delimiters should be left.
+ var following = parameters[index + 1];
+ builder.addDeletion(range.startStart(parameter, following));
+ }
+ } else {
+ // The parameter to be removed and the preceding parameter are of
+ // the same kind, so there is no delimiter between them.
+ builder.addDeletion(range.endEnd(preceding, parameter));
+ }
+ }
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnusedParameter newInstance() => RemoveUnusedParameter();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart
new file mode 100644
index 0000000..a133a81
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_return_type_future.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ReplaceReturnTypeFuture extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_RETURN_TYPE_FUTURE;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ // prepare the existing type
+ var typeName = node.thisOrAncestorOfType<TypeAnnotation>();
+ var typeProvider = this.typeProvider;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.replaceTypeWithFuture(typeName, typeProvider);
+ });
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceReturnTypeFuture newInstance() => ReplaceReturnTypeFuture();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart
new file mode 100644
index 0000000..a52370f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_extension_name.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class ReplaceWithExtensionName extends CorrectionProducer {
+ String _extensionName;
+
+ @override
+ List<Object> get fixArguments => [_extensionName];
+
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_WITH_EXTENSION_NAME;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ var target = _getTarget(node.parent);
+ if (target is ExtensionOverride) {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.node(target), utils.getNodeText(target.extensionName));
+ });
+ _extensionName = target.extensionName.name;
+ }
+ }
+
+ AstNode _getTarget(AstNode invocation) {
+ if (invocation is MethodInvocation && node == invocation.methodName) {
+ return invocation.target;
+ } else if (invocation is PropertyAccess &&
+ node == invocation.propertyName) {
+ return invocation.target;
+ }
+ return null;
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceWithExtensionName newInstance() => ReplaceWithExtensionName();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
index 54306ba..31b6a19 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/shadow_field.dart
@@ -100,6 +100,9 @@
}
return null;
}
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ShadowField newInstance() => ShadowField();
}
/// A utility that will find any references to a setter within an AST structure.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart b/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart
index 3fdefb9..c4fa305 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/split_and_condition.dart
@@ -97,4 +97,7 @@
}
});
}
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static SplitAndCondition newInstance() => SplitAndCondition();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart
new file mode 100644
index 0000000..c73a6e6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_const.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseConst extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_CONST;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is InstanceCreationExpression) {
+ var instanceCreation = coveredNode as InstanceCreationExpression;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (instanceCreation.keyword == null) {
+ builder.addSimpleInsertion(
+ instanceCreation.constructorName.offset, 'const');
+ } else {
+ builder.addSimpleReplacement(
+ range.token(instanceCreation.keyword), 'const');
+ }
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UseConst newInstance() => UseConst();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart
new file mode 100644
index 0000000..97a1d2a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_effective_integer_division.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseEffectiveIntegerDivision extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ for (var n = node; n != null; n = n.parent) {
+ if (n is MethodInvocation &&
+ n.offset == errorOffset &&
+ n.length == errorLength) {
+ var target = (n as MethodInvocation).target.unParenthesized;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ // replace "/" with "~/"
+ var binary = target as BinaryExpression;
+ builder.addSimpleReplacement(range.token(binary.operator), '~/');
+ // remove everything before and after
+ builder.addDeletion(range.startStart(n, binary.leftOperand));
+ builder.addDeletion(range.endEnd(binary.rightOperand, n));
+ });
+ // done
+ break;
+ }
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UseEffectiveIntegerDivision newInstance() =>
+ UseEffectiveIntegerDivision();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart
new file mode 100644
index 0000000..c51598e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_eq_eq_null.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseEqEqNull extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_EQ_EQ_NULL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is IsExpression) {
+ var isExpression = coveredNode as IsExpression;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder
+ .addReplacement(range.endEnd(isExpression.expression, isExpression),
+ (DartEditBuilder builder) {
+ builder.write(' == null');
+ });
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UseEqEqNull newInstance() => UseEqEqNull();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart
new file mode 100644
index 0000000..f699074
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/use_not_eq_null.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class UseNotEqNull extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.USE_NOT_EQ_NULL;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ if (coveredNode is IsExpression) {
+ var isExpression = coveredNode as IsExpression;
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder
+ .addReplacement(range.endEnd(isExpression.expression, isExpression),
+ (DartEditBuilder builder) {
+ builder.write(' != null');
+ });
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static UseNotEqNull newInstance() => UseNotEqNull();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart b/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
index 522ca6d..6ced314 100644
--- a/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/executable_parameters.dart
@@ -25,7 +25,7 @@
if (invocation is Annotation) {
element = invocation.element;
} else if (invocation is InstanceCreationExpression) {
- element = invocation.staticElement;
+ element = invocation.constructorName.staticElement;
} else if (invocation is MethodInvocation) {
element = invocation.methodName.staticElement;
} else if (invocation is ConstructorReferenceNode) {
@@ -58,7 +58,8 @@
return named.map((parameter) => parameter.name).toList();
}
- /// Return the [FormalParameterList] of the [executable], or `nul be found.
+ /// Return the [FormalParameterList] of the [executable], or `null` if it
+ /// can't be found.
Future<FormalParameterList> getParameterList() async {
var result = await sessionHelper.getElementDeclaration(executable);
var targetDeclaration = result.node;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 8411deb..c1caa95 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -394,6 +394,8 @@
'dart.fix.remove.unusedLocalVariable',
50,
'Remove unused local variable');
+ static const REMOVE_UNUSED_PARAMETER = FixKind(
+ 'dart.fix.remove.unusedParameter', 50, 'Remove the unused parameter');
static const RENAME_TO_CAMEL_CASE =
FixKind('dart.fix.rename.toCamelCase', 50, "Rename to '{0}'");
static const REPLACE_BOOLEAN_WITH_BOOL = 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 131e355..ee81b66 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -5,7 +5,6 @@
import 'dart:async';
import 'dart:collection';
import 'dart:core';
-import 'dart:math' as math;
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
@@ -18,7 +17,9 @@
import 'package:analysis_server/src/services/correction/dart/add_explicit_cast.dart';
import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
import 'package:analysis_server/src/services/correction/dart/add_missing_enum_case_clauses.dart';
+import 'package:analysis_server/src/services/correction/dart/add_missing_parameter_named.dart';
import 'package:analysis_server/src/services/correction/dart/add_missing_required_argument.dart';
+import 'package:analysis_server/src/services/correction/dart/add_ne_null.dart';
import 'package:analysis_server/src/services/correction/dart/add_override.dart';
import 'package:analysis_server/src/services/correction/dart/add_required.dart';
import 'package:analysis_server/src/services/correction/dart/add_required_keyword.dart';
@@ -27,6 +28,7 @@
import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/change_argument_name.dart';
import 'package:analysis_server/src/services/correction/dart/change_to_nearest_precise_value.dart';
+import 'package:analysis_server/src/services/correction/dart/change_to_static_access.dart';
import 'package:analysis_server/src/services/correction/dart/change_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
import 'package:analysis_server/src/services/correction/dart/convert_conditional_expression_to_if_element.dart';
@@ -49,13 +51,30 @@
import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
+import 'package:analysis_server/src/services/correction/dart/create_class.dart';
+import 'package:analysis_server/src/services/correction/dart/create_constructor_for_final_fields.dart';
+import 'package:analysis_server/src/services/correction/dart/create_getter.dart';
+import 'package:analysis_server/src/services/correction/dart/create_local_variable.dart';
import 'package:analysis_server/src/services/correction/dart/create_method.dart';
+import 'package:analysis_server/src/services/correction/dart/create_missing_overrides.dart';
+import 'package:analysis_server/src/services/correction/dart/create_mixin.dart';
+import 'package:analysis_server/src/services/correction/dart/create_no_such_method.dart';
+import 'package:analysis_server/src/services/correction/dart/create_setter.dart';
+import 'package:analysis_server/src/services/correction/dart/extend_class_for_mixin.dart';
import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
import 'package:analysis_server/src/services/correction/dart/inline_typedef.dart';
+import 'package:analysis_server/src/services/correction/dart/insert_semicolon.dart';
+import 'package:analysis_server/src/services/correction/dart/make_class_abstract.dart';
+import 'package:analysis_server/src/services/correction/dart/make_field_not_final.dart';
import 'package:analysis_server/src/services/correction/dart/make_final.dart';
+import 'package:analysis_server/src/services/correction/dart/make_variable_not_final.dart';
+import 'package:analysis_server/src/services/correction/dart/move_type_arguments_to_class.dart';
+import 'package:analysis_server/src/services/correction/dart/qualify_reference.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/remove_argument.dart';
import 'package:analysis_server/src/services/correction/dart/remove_await.dart';
import 'package:analysis_server/src/services/correction/dart/remove_const.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_dead_code.dart';
import 'package:analysis_server/src/services/correction/dart/remove_dead_if_null.dart';
import 'package:analysis_server/src/services/correction/dart/remove_duplicate_case.dart';
import 'package:analysis_server/src/services/correction/dart/remove_empty_catch.dart';
@@ -66,22 +85,34 @@
import 'package:analysis_server/src/services/correction/dart/remove_initializer.dart';
import 'package:analysis_server/src/services/correction/dart/remove_interpolation_braces.dart';
import 'package:analysis_server/src/services/correction/dart/remove_method_declaration.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_name_from_combinator.dart';
import 'package:analysis_server/src/services/correction/dart/remove_operator.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_parameters_in_getter_declaration.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart';
import 'package:analysis_server/src/services/correction/dart/remove_question_mark.dart';
import 'package:analysis_server/src/services/correction/dart/remove_this_expression.dart';
import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_type_arguments.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_cast.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_new.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_catch_clause.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_catch_stack.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_import.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_label.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused_local_variable.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unused_parameter.dart';
import 'package:analysis_server/src/services/correction/dart/rename_to_camel_case.dart';
import 'package:analysis_server/src/services/correction/dart/replace_boolean_with_bool.dart';
import 'package:analysis_server/src/services/correction/dart/replace_colon_with_equals.dart';
import 'package:analysis_server/src/services/correction/dart/replace_final_with_const.dart';
import 'package:analysis_server/src/services/correction/dart/replace_new_with_const.dart';
import 'package:analysis_server/src/services/correction/dart/replace_null_with_closure.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_return_type_future.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_brackets.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_conditional_assignment.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_extension_name.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_identifier.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_is_empty.dart';
@@ -90,11 +121,16 @@
import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
import 'package:analysis_server/src/services/correction/dart/sort_child_property_last.dart';
import 'package:analysis_server/src/services/correction/dart/sort_directives.dart';
+import 'package:analysis_server/src/services/correction/dart/use_const.dart';
import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
+import 'package:analysis_server/src/services/correction/dart/use_effective_integer_division.dart';
+import 'package:analysis_server/src/services/correction/dart/use_eq_eq_null.dart';
import 'package:analysis_server/src/services/correction/dart/use_is_not_empty.dart';
+import 'package:analysis_server/src/services/correction/dart/use_not_eq_null.dart';
import 'package:analysis_server/src/services/correction/dart/use_rethrow.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_future.dart';
import 'package:analysis_server/src/services/correction/dart/wrap_in_text.dart';
+import 'package:analysis_server/src/services/correction/executable_parameters.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
import 'package:analysis_server/src/services/correction/levenshtein.dart';
@@ -102,10 +138,7 @@
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
-import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/precedence.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -113,12 +146,9 @@
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/error/inheritance_override.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/parser.dart';
@@ -293,6 +323,9 @@
ReplaceWithIdentifier.newInstance,
RemoveTypeAnnotation.newInstance,
],
+ LintNames.avoid_unused_constructor_parameters: [
+ RemoveUnusedParameter.newInstance,
+ ],
LintNames.await_only_futures: [
RemoveAwait.newInstance,
],
@@ -385,6 +418,7 @@
ConvertToIfNull.newInstance,
],
LintNames.prefer_inlined_adds: [
+ ConvertAddAllToSpread.newInstance,
InlineInvocation.newInstance,
],
LintNames.prefer_int_literals: [
@@ -475,14 +509,18 @@
CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT: [
AddSync.newInstance,
],
-// CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE : [],
+ CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE: [
+ UseConst.newInstance,
+ ],
CompileTimeErrorCode.CONST_INSTANCE_FIELD: [
AddStatic.newInstance,
],
CompileTimeErrorCode.CONST_WITH_NON_CONST: [
RemoveConst.newInstance,
],
-// CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER : [],
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER: [
+ ReplaceWithExtensionName.newInstance,
+ ],
// CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : [],
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED: [
ConvertToNamedArguments.newInstance,
@@ -491,11 +529,15 @@
CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE: [
ChangeToNearestPreciseValue.newInstance,
],
-// CompileTimeErrorCode.INVALID_ANNOTATION : [],
+ CompileTimeErrorCode.INVALID_ANNOTATION: [
+ CreateClass.newInstance,
+ ],
CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
AddRequiredKeyword.newInstance,
],
-// CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE : [],
+ CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE: [
+ ExtendClassForMixin.newInstance,
+ ],
// CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT : [],
// CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT : [],
CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE: [
@@ -510,36 +552,84 @@
CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE: [
RemoveQuestionMark.newInstance,
],
-// CompileTimeErrorCode.UNDEFINED_ANNOTATION : [],
-// CompileTimeErrorCode.UNDEFINED_CLASS : [],
+ CompileTimeErrorCode.UNDEFINED_ANNOTATION: [
+ CreateClass.newInstance,
+ ],
+ CompileTimeErrorCode.UNDEFINED_CLASS: [
+ CreateClass.newInstance,
+ CreateMixin.newInstance,
+ ],
// CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT : [],
-// CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER : [],
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER: [
+ CreateGetter.newInstance,
+ ],
// CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD : [],
-// CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER : [],
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER: [
+ CreateSetter.newInstance,
+ ],
CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER: [
+ AddMissingParameterNamed.newInstance,
ConvertFlutterChild.newInstance,
ConvertFlutterChildren.newInstance,
],
-// CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE : [],
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE: [
+ // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
+ // method or setter. The existing _addFix methods would need to be
+ // updated so that only the appropriate subset is generated.
+ QualifyReference.newInstance,
+ ],
// CompileTimeErrorCode.URI_DOES_NOT_EXIST : [],
HintCode.CAN_BE_NULL_AFTER_NULL_AWARE: [
ReplaceWithNullAware.newInstance,
],
-// HintCode.DEAD_CODE : [],
-// HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH : [],
-// HintCode.DEAD_CODE_ON_CATCH_SUBTYPE : [],
-// HintCode.DIVISION_OPTIMIZATION : [],
-// HintCode.DUPLICATE_HIDDEN_NAME : [],
-// HintCode.DUPLICATE_IMPORT : [],
-// HintCode.DUPLICATE_SHOWN_NAME : [],
-// HintCode.INVALID_FACTORY_ANNOTATION : [],
-// HintCode.INVALID_IMMUTABLE_ANNOTATION : [],
-// HintCode.INVALID_LITERAL_ANNOTATION : [],
-// HintCode.INVALID_REQUIRED_NAMED_PARAM : [],
-// HintCode.INVALID_REQUIRED_OPTIONAL_POSITIONAL_PARAM : [],
-// HintCode.INVALID_REQUIRED_POSITIONAL_PARAM : [],
-// HintCode.INVALID_SEALED_ANNOTATION : [],
+ HintCode.DEAD_CODE: [
+ RemoveDeadCode.newInstance,
+ ],
+ HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH: [
+ // TODO(brianwilkerson) Add a fix to move the unreachable catch clause to
+ // a place where it can be reached (when possible).
+ RemoveDeadCode.newInstance,
+ ],
+ HintCode.DEAD_CODE_ON_CATCH_SUBTYPE: [
+ // TODO(brianwilkerson) Add a fix to move the unreachable catch clause to
+ // a place where it can be reached (when possible).
+ RemoveDeadCode.newInstance,
+ ],
+ HintCode.DIVISION_OPTIMIZATION: [
+ UseEffectiveIntegerDivision.newInstance,
+ ],
+ HintCode.DUPLICATE_HIDDEN_NAME: [
+ RemoveNameFromCombinator.newInstance,
+ ],
+ HintCode.DUPLICATE_IMPORT: [
+ RemoveUnusedImport.newInstance,
+ ],
+ HintCode.DUPLICATE_SHOWN_NAME: [
+ RemoveNameFromCombinator.newInstance,
+ ],
+ HintCode.INVALID_FACTORY_ANNOTATION: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_IMMUTABLE_ANNOTATION: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_LITERAL_ANNOTATION: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_REQUIRED_NAMED_PARAM: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_REQUIRED_OPTIONAL_POSITIONAL_PARAM: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_REQUIRED_POSITIONAL_PARAM: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.INVALID_SEALED_ANNOTATION: [
+ RemoveAnnotation.newInstance,
+ ],
HintCode.MISSING_REQUIRED_PARAM: [
AddMissingRequiredArgument.newInstance,
],
@@ -549,10 +639,18 @@
HintCode.NULLABLE_TYPE_IN_CATCH_CLAUSE: [
RemoveQuestionMark.newInstance,
],
-// HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD : [],
-// HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER : [],
-// HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD : [],
-// HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER : [],
+ HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD: [
+ RemoveAnnotation.newInstance,
+ ],
+ HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER: [
+ RemoveAnnotation.newInstance,
+ ],
// HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT : [],
// HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE : [],
// HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT : [],
@@ -562,60 +660,127 @@
// HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT : [],
// HintCode.SDK_VERSION_SET_LITERAL : [],
// HintCode.SDK_VERSION_UI_AS_CODE : [],
-// HintCode.TYPE_CHECK_IS_NOT_NULL : [],
-// HintCode.TYPE_CHECK_IS_NULL : [],
-// HintCode.UNDEFINED_HIDDEN_NAME : [],
-// HintCode.UNDEFINED_SHOWN_NAME : [],
-// HintCode.UNNECESSARY_CAST : [],
-// HintCode.UNUSED_CATCH_CLAUSE : [],
-// HintCode.UNUSED_CATCH_STACK : [],
+ HintCode.TYPE_CHECK_IS_NOT_NULL: [
+ UseNotEqNull.newInstance,
+ ],
+ HintCode.TYPE_CHECK_IS_NULL: [
+ UseEqEqNull.newInstance,
+ ],
+ HintCode.UNDEFINED_HIDDEN_NAME: [
+ RemoveNameFromCombinator.newInstance,
+ ],
+ HintCode.UNDEFINED_SHOWN_NAME: [
+ RemoveNameFromCombinator.newInstance,
+ ],
+ HintCode.UNNECESSARY_CAST: [
+ RemoveUnnecessaryCast.newInstance,
+ ],
+ HintCode.UNUSED_CATCH_CLAUSE: [
+ RemoveUnusedCatchClause.newInstance,
+ ],
+ HintCode.UNUSED_CATCH_STACK: [
+ RemoveUnusedCatchStack.newInstance,
+ ],
HintCode.UNUSED_ELEMENT: [
RemoveUnusedElement.newInstance,
],
HintCode.UNUSED_FIELD: [
RemoveUnusedField.newInstance,
],
-// HintCode.UNUSED_IMPORT : [],
-// HintCode.UNUSED_LABEL : [],
+ HintCode.UNUSED_IMPORT: [
+ RemoveUnusedImport.newInstance,
+ ],
+ HintCode.UNUSED_LABEL: [
+ RemoveUnusedLabel.newInstance,
+ ],
HintCode.UNUSED_LOCAL_VARIABLE: [
RemoveUnusedLocalVariable.newInstance,
],
-// HintCode.UNUSED_SHOWN_NAME : [],
+ HintCode.UNUSED_SHOWN_NAME: [
+ RemoveNameFromCombinator.newInstance,
+ ],
-// ParserErrorCode.EXPECTED_TOKEN : [],
-// ParserErrorCode.GETTER_WITH_PARAMETERS : [],
+ ParserErrorCode.EXPECTED_TOKEN: [
+ InsertSemicolon.newInstance,
+ ],
+ ParserErrorCode.GETTER_WITH_PARAMETERS: [
+ RemoveParametersInGetterDeclaration.newInstance,
+ ],
ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE: [
AddTypeAnnotation.newInstance,
],
// ParserErrorCode.VAR_AS_TYPE_NAME : [],
-// StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE : [],
-// StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER : [],
+ StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE: [
+ ReplaceReturnTypeFuture.newInstance,
+ ],
+ StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER: [
+ ChangeToStaticAccess.newInstance,
+ ],
StaticTypeWarningCode.INVALID_ASSIGNMENT: [
AddExplicitCast.newInstance,
ChangeTypeAnnotation.newInstance,
],
-// StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION : [],
-// StaticTypeWarningCode.NON_BOOL_CONDITION : [],
-// StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT : [],
-// StaticTypeWarningCode.UNDEFINED_FUNCTION : [],
-// StaticTypeWarningCode.UNDEFINED_GETTER : [],
-// StaticTypeWarningCode.UNDEFINED_METHOD : [],
-// StaticTypeWarningCode.UNDEFINED_SETTER : [],
-// StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR : [],
-// StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER : [],
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION: [
+ RemoveParenthesesInGetterInvocation.newInstance,
+ ],
+ StaticTypeWarningCode.NON_BOOL_CONDITION: [
+ AddNeNull.newInstance,
+ ],
+ StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT: [
+ CreateClass.newInstance,
+ CreateMixin.newInstance,
+ ],
+ StaticTypeWarningCode.UNDEFINED_FUNCTION: [
+ CreateClass.newInstance,
+ ],
+ StaticTypeWarningCode.UNDEFINED_GETTER: [
+ CreateClass.newInstance,
+ CreateGetter.newInstance,
+ CreateLocalVariable.newInstance,
+ CreateMixin.newInstance,
+ ],
+ StaticTypeWarningCode.UNDEFINED_METHOD: [
+ CreateClass.newInstance,
+ ],
+ StaticTypeWarningCode.UNDEFINED_SETTER: [
+ CreateSetter.newInstance,
+ ],
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR: [
+ MoveTypeArgumentsToClass.newInstance,
+ RemoveTypeArguments.newInstance,
+ ],
+ StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER: [
+ // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
+ // method or setter. The existing _addFix methods would need to be
+ // updated so that only the appropriate subset is generated.
+ QualifyReference.newInstance,
+ ],
-// StaticWarningCode.ASSIGNMENT_TO_FINAL : [],
-// StaticWarningCode.ASSIGNMENT_TO_FINAL_LOCAL : [],
+ StaticWarningCode.ASSIGNMENT_TO_FINAL: [
+ MakeFieldNotFinal.newInstance,
+ ],
+ StaticWarningCode.ASSIGNMENT_TO_FINAL_LOCAL: [
+ MakeVariableNotFinal.newInstance,
+ ],
StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE: [
WrapInText.newInstance,
],
-// StaticWarningCode.CAST_TO_NON_TYPE : [],
-// StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER : [],
+ StaticWarningCode.CAST_TO_NON_TYPE: [
+ CreateClass.newInstance,
+ CreateMixin.newInstance,
+ ],
+ StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
+ ],
StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION: [
RemoveDeadIfNull.newInstance,
],
-// StaticWarningCode.FINAL_NOT_INITIALIZED : [],
+ StaticWarningCode.FINAL_NOT_INITIALIZED: [
+ CreateConstructorForFinalFields.newInstance,
+ ],
StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1: [
AddFieldFormalParameters.newInstance,
],
@@ -629,18 +794,50 @@
AddMissingEnumCaseClauses.newInstance,
],
// StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR : [],
-// StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS : [],
-// StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR : [],
-// StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE : [],
-// StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE : [],
-// StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO : [],
-// StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE : [],
-// StaticWarningCode.NOT_A_TYPE : [],
-// StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME : [],
- StaticWarningCode.UNDEFINED_CLASS_BOOLEAN: [
- ReplaceBooleanWithBool.newInstance
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
],
-// StaticWarningCode.UNDEFINED_IDENTIFIER : [],
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
+ ],
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
+ ],
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
+ ],
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO: [
+ CreateMissingOverrides.newInstance,
+ CreateNoSuchMethod.newInstance,
+ MakeClassAbstract.newInstance,
+ ],
+// StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE : [],
+ StaticWarningCode.NOT_A_TYPE: [
+ CreateClass.newInstance,
+ CreateMixin.newInstance,
+ ],
+ StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME: [
+ CreateClass.newInstance,
+ CreateMixin.newInstance,
+ ],
+ StaticWarningCode.UNDEFINED_CLASS_BOOLEAN: [
+ ReplaceBooleanWithBool.newInstance,
+ ],
+ StaticWarningCode.UNDEFINED_IDENTIFIER: [
+ CreateClass.newInstance,
+ CreateGetter.newInstance,
+ CreateLocalVariable.newInstance,
+ CreateMixin.newInstance,
+ CreateSetter.newInstance,
+ ],
StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT: [
AddSync.newInstance,
],
@@ -661,8 +858,6 @@
final List<Fix> fixes = <Fix>[];
- AstNode coveredNode;
-
FixProcessor(this.context)
: resourceProvider = context.resolveResult.session.resourceProvider,
typeSystem = context.resolveResult.typeSystem,
@@ -678,28 +873,11 @@
DartType get coreTypeBool => context.resolveResult.typeProvider.boolType;
- FeatureSet get _featureSet {
- return unit.featureSet;
- }
-
- bool get _isNonNullable => _featureSet.isEnabled(Feature.non_nullable);
-
Future<List<Fix>> compute() async {
node = NodeLocator2(errorOffset).searchWithin(unit);
- coveredNode =
- NodeLocator2(errorOffset, math.max(errorOffset + errorLength - 1, 0))
- .searchWithin(unit);
- if (coveredNode == null) {
- // TODO(brianwilkerson) Figure out why the coveredNode is sometimes null.
- return fixes;
- }
// analyze ErrorCode
var errorCode = error.errorCode;
- if (errorCode ==
- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
- await _addFix_replaceWithConstInstanceCreation();
- }
if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION ||
errorCode == CompileTimeErrorCode.UNDEFINED_ANNOTATION) {
if (node is Annotation) {
@@ -711,7 +889,6 @@
await _addFix_importLibrary_withTopLevelVariable();
} else {
await _addFix_importLibrary_withType();
- await _addFix_createClass();
await _addFix_undefinedClass_useSimilar();
}
}
@@ -737,50 +914,16 @@
await _addFix_createImportUri();
await _addFix_createPartUri();
}
- if (errorCode == HintCode.DEAD_CODE) {
- await _addFix_removeDeadCode();
- }
- if (errorCode == HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH ||
- errorCode == HintCode.DEAD_CODE_ON_CATCH_SUBTYPE) {
- await _addFix_removeDeadCode();
- // TODO(brianwilkerson) Add a fix to move the unreachable catch clause to
- // a place where it can be reached (when possible).
- }
// TODO(brianwilkerson) Define a syntax for deprecated members to indicate
// how to update the code and implement a fix to apply the update.
// if (errorCode == HintCode.DEPRECATED_MEMBER_USE ||
// errorCode == HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE) {
// await _addFix_replaceDeprecatedMemberUse();
// }
- if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
- await _addFix_useEffectiveIntegerDivision();
- }
- if (errorCode == HintCode.DUPLICATE_IMPORT) {
- await _addFix_removeUnusedImport();
- }
- if (errorCode == HintCode.DUPLICATE_HIDDEN_NAME ||
- errorCode == HintCode.DUPLICATE_SHOWN_NAME) {
- await _addFix_removeNameFromCombinator();
- }
// TODO(brianwilkerson) Add a fix to convert the path to a package: import.
// if (errorCode == HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE) {
// await _addFix_convertPathToPackageUri();
// }
- if (errorCode == HintCode.INVALID_FACTORY_ANNOTATION ||
- errorCode == HintCode.INVALID_IMMUTABLE_ANNOTATION ||
- errorCode == HintCode.INVALID_LITERAL_ANNOTATION ||
- errorCode == HintCode.INVALID_REQUIRED_NAMED_PARAM ||
- errorCode == HintCode.INVALID_REQUIRED_OPTIONAL_POSITIONAL_PARAM ||
- errorCode == HintCode.INVALID_REQUIRED_POSITIONAL_PARAM ||
- errorCode == HintCode.INVALID_SEALED_ANNOTATION) {
- await _addFix_removeAnnotation();
- }
- if (errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER ||
- errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD ||
- errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD ||
- errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER) {
- await _addFix_removeAnnotation();
- }
// TODO(brianwilkerson) Add a fix to normalize the path.
// if (errorCode == HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT) {
// await _addFix_normalizeUri();
@@ -803,19 +946,6 @@
if (errorCode == HintCode.SDK_VERSION_EXTENSION_METHODS) {
await _addFix_updateSdkConstraints('2.6.0');
}
- if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
- await _addFix_isNotNull();
- }
- if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
- await _addFix_isNull();
- }
- if (errorCode == HintCode.UNDEFINED_HIDDEN_NAME ||
- errorCode == HintCode.UNDEFINED_SHOWN_NAME) {
- await _addFix_removeNameFromCombinator();
- }
- if (errorCode == HintCode.UNNECESSARY_CAST) {
- await _addFix_removeUnnecessaryCast();
- }
// TODO(brianwilkerson) Add a fix to remove the method.
// if (errorCode == HintCode.UNNECESSARY_NO_SUCH_METHOD) {
// await _addFix_removeMethodDeclaration();
@@ -825,39 +955,9 @@
// errorCode == HintCode.UNNECESSARY_TYPE_CHECK_TRUE) {
// await _addFix_removeUnnecessaryTypeCheck();
// }
- if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) {
- await _addFix_removeUnusedCatchClause();
- }
- if (errorCode == HintCode.UNUSED_CATCH_STACK) {
- await _addFix_removeUnusedCatchStack();
- }
- if (errorCode == HintCode.UNUSED_IMPORT) {
- await _addFix_removeUnusedImport();
- }
- if (errorCode == HintCode.UNUSED_LABEL) {
- await _addFix_removeUnusedLabel();
- }
- if (errorCode == HintCode.UNUSED_SHOWN_NAME) {
- await _addFix_removeNameFromCombinator();
- }
- if (errorCode == ParserErrorCode.EXPECTED_TOKEN) {
- await _addFix_insertSemicolon();
- }
- if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) {
- await _addFix_removeParameters_inGetterDeclaration();
- }
if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
await _addFix_replaceVarWithDynamic();
}
- if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
- await _addFix_makeFieldNotFinal();
- }
- if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL_LOCAL) {
- await _addFix_makeVariableNotFinal();
- }
- if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) {
- await _addFix_makeEnclosingClassAbstract();
- }
if (errorCode == CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS ||
errorCode ==
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED) {
@@ -867,79 +967,32 @@
if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
await _addFix_createConstructor_named();
}
- if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
- errorCode ==
- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO ||
- errorCode ==
- StaticWarningCode
- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
- errorCode ==
- StaticWarningCode
- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
- errorCode ==
- StaticWarningCode
- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
- // make class abstract
- await _addFix_makeEnclosingClassAbstract();
- await _addFix_createNoSuchMethod();
- // implement methods
- await _addFix_createMissingOverrides();
- }
- if (errorCode == CompileTimeErrorCode.UNDEFINED_CLASS ||
+ if (errorCode == CompileTimeErrorCode.CONST_WITH_NON_TYPE ||
+ errorCode == CompileTimeErrorCode.MIXIN_OF_NON_CLASS ||
+ errorCode == CompileTimeErrorCode.UNDEFINED_CLASS ||
errorCode == StaticWarningCode.CAST_TO_NON_TYPE ||
+ errorCode == StaticWarningCode.NEW_WITH_NON_TYPE ||
errorCode == StaticWarningCode.NOT_A_TYPE ||
errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME) {
await _addFix_importLibrary_withType();
- await _addFix_createClass();
- await _addFix_createMixin();
await _addFix_undefinedClass_useSimilar();
}
if (errorCode == StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE) {
await _addFix_importLibrary_withType();
}
- if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) {
- await _addFix_createConstructor_forUninitializedFinalFields();
- }
if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
await _addFix_undefinedClassAccessor_useSimilar();
- await _addFix_createClass();
await _addFix_createField();
- await _addFix_createGetter();
await _addFix_createFunction_forFunctionType();
- await _addFix_createMixin();
- await _addFix_createSetter();
await _addFix_importLibrary_withType();
await _addFix_importLibrary_withExtension();
await _addFix_importLibrary_withFunction();
await _addFix_importLibrary_withTopLevelVariable();
- await _addFix_createLocalVariable();
- }
- if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER) {
- await _addFix_addMissingParameterNamed();
- }
- if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
- await _addFix_illegalAsyncReturnType();
- }
- if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
- await _addFix_useStaticAccess_method();
- await _addFix_useStaticAccess_property();
- }
- if (errorCode ==
- StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION) {
- await _addFix_removeParentheses_inGetterInvocation();
- }
- if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) {
- await _addFix_nonBoolCondition_addNotNull();
}
if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) {
await _addFix_importLibrary_withType();
- await _addFix_createClass();
- await _addFix_createMixin();
}
if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) {
- await _addFix_createClass();
await _addFix_importLibrary_withExtension();
await _addFix_importLibrary_withFunction();
await _addFix_importLibrary_withType();
@@ -949,22 +1002,14 @@
if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
await _addFix_undefinedClassAccessor_useSimilar();
await _addFix_createField();
- await _addFix_createGetter();
await _addFix_createFunction_forFunctionType();
- // TODO(brianwilkerson) The following were added because fasta produces
- // UNDEFINED_GETTER in places where analyzer produced UNDEFINED_IDENTIFIER
- await _addFix_createClass();
- await _addFix_createMixin();
- await _addFix_createLocalVariable();
await _addFix_importLibrary_withTopLevelVariable();
await _addFix_importLibrary_withType();
}
if (errorCode == CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER) {
await _addFix_undefinedClassAccessor_useSimilar();
- await _addFix_createGetter();
}
if (errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
- await _addFix_createClass();
await _addFix_importLibrary_withFunction();
await _addFix_importLibrary_withType();
await _addFix_undefinedMethod_useSimilar();
@@ -978,45 +1023,14 @@
if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) {
await _addFix_undefinedClassAccessor_useSimilar();
await _addFix_createField();
- await _addFix_createSetter();
}
if (errorCode == CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER) {
await _addFix_undefinedClassAccessor_useSimilar();
- await _addFix_createSetter();
}
if (errorCode ==
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD) {
await _addFix_createField_initializingFormal();
}
- if (errorCode ==
- StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR) {
- await _addFix_moveTypeArgumentsToClass();
- await _addFix_removeTypeArguments();
- }
- if (errorCode ==
- CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE) {
- await _addFix_extendClassForMixin();
- }
- if (errorCode ==
- CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER) {
- await _addFix_replaceWithExtensionName();
- }
- if (errorCode ==
- CompileTimeErrorCode
- .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE) {
- await _addFix_qualifyReference();
- // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
- // method or setter. The existing _addFix methods would need to be
- // updated so that only the appropriate subset is generated.
- }
- if (errorCode ==
- StaticTypeWarningCode
- .UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER) {
- await _addFix_qualifyReference();
- // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
- // method or setter. The existing _addFix methods would need to be
- // updated so that only the appropriate subset is generated.
- }
await _addFromProducers();
// done
@@ -1038,7 +1052,7 @@
List<Expression> arguments = argumentList.arguments;
// Prepare the invoked element.
- var context = _ExecutableParameters(sessionHelper, node.parent);
+ var context = ExecutableParameters(sessionHelper, node.parent);
if (context == null) {
return;
}
@@ -1095,227 +1109,6 @@
}
}
- Future<void> _addFix_addMissingParameterNamed() async {
- // Prepare the name of the missing parameter.
- if (this.node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier node = this.node;
- var name = node.name;
-
- // We expect that the node is part of a NamedExpression.
- if (node.parent?.parent is! NamedExpression) {
- return;
- }
- NamedExpression namedExpression = node.parent.parent;
-
- // We should be in an ArgumentList.
- if (namedExpression.parent is! ArgumentList) {
- return;
- }
- var argumentList = namedExpression.parent;
-
- // Prepare the invoked element.
- var context = _ExecutableParameters(sessionHelper, argumentList.parent);
- if (context == null) {
- return;
- }
-
- // We cannot add named parameters when there are positional positional.
- if (context.optionalPositional.isNotEmpty) {
- return;
- }
-
- Future<void> addParameter(int offset, String prefix, String suffix) async {
- if (offset != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(context.file, (builder) {
- builder.addInsertion(offset, (builder) {
- builder.write(prefix);
- builder
- .writeParameterMatchingArgument(namedExpression, 0, <String>{});
- builder.write(suffix);
- });
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_NAMED,
- args: [name]);
- }
- }
-
- if (context.named.isNotEmpty) {
- var prevNode = await context.getParameterNode(context.named.last);
- await addParameter(prevNode?.end, ', ', '');
- } else if (context.required.isNotEmpty) {
- var prevNode = await context.getParameterNode(context.required.last);
- await addParameter(prevNode?.end, ', {', '}');
- } else {
- var parameterList = await context.getParameterList();
- await addParameter(parameterList?.leftParenthesis?.end, '{', '}');
- }
- }
-
- Future<void> _addFix_createClass() async {
- Element prefixElement;
- String name;
- SimpleIdentifier nameNode;
- if (node is SimpleIdentifier) {
- var parent = node.parent;
- if (parent is PrefixedIdentifier) {
- PrefixedIdentifier prefixedIdentifier = parent;
- prefixElement = prefixedIdentifier.prefix.staticElement;
- if (prefixElement == null) {
- return;
- }
- parent = prefixedIdentifier.parent;
- nameNode = prefixedIdentifier.identifier;
- name = prefixedIdentifier.identifier.name;
- } else {
- nameNode = node;
- name = nameNode.name;
- }
- if (!_mayBeTypeIdentifier(nameNode)) {
- return;
- }
- } else {
- return;
- }
- // prepare environment
- Element targetUnit;
- var prefix = '';
- var suffix = '';
- var offset = -1;
- String filePath;
- if (prefixElement == null) {
- targetUnit = unit.declaredElement;
- var enclosingMember = node.thisOrAncestorMatching((node) =>
- node is CompilationUnitMember && node.parent is CompilationUnit);
- if (enclosingMember == null) {
- return;
- }
- offset = enclosingMember.end;
- filePath = file;
- prefix = '$eol$eol';
- } else {
- for (var import in unitLibraryElement.imports) {
- if (prefixElement is PrefixElement && import.prefix == prefixElement) {
- var library = import.importedLibrary;
- if (library != null) {
- targetUnit = library.definingCompilationUnit;
- var targetSource = targetUnit.source;
- try {
- offset = targetSource.contents.data.length;
- filePath = targetSource.fullName;
- prefix = '$eol';
- suffix = '$eol';
- } on FileSystemException {
- // If we can't read the file to get the offset, then we can't
- // create a fix.
- }
- break;
- }
- }
- }
- }
- if (offset < 0) {
- return;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(filePath, (DartFileEditBuilder builder) {
- builder.addInsertion(offset, (DartEditBuilder builder) {
- builder.write(prefix);
- builder.writeClassDeclaration(name, nameGroupName: 'NAME');
- builder.write(suffix);
- });
- if (prefixElement == null) {
- builder.addLinkedPosition(range.node(node), 'NAME');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CLASS, args: [name]);
- }
-
- /// Here we handle cases when there are no constructors in a class, and the
- /// class has uninitialized final fields.
- Future<void> _addFix_createConstructor_forUninitializedFinalFields() async {
- if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) {
- return;
- }
-
- var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
- if (classDeclaration == null) {
- return;
- }
- var className = classDeclaration.name.name;
- var superType = classDeclaration.declaredElement.supertype;
-
- // prepare names of uninitialized final fields
- var fieldNames = <String>[];
- for (var member in classDeclaration.members) {
- if (member is FieldDeclaration) {
- var variableList = member.fields;
- if (variableList.isFinal) {
- fieldNames.addAll(variableList.variables
- .where((v) => v.initializer == null)
- .map((v) => v.name.name));
- }
- }
- }
- // prepare location for a new constructor
- var targetLocation = utils.prepareNewConstructorLocation(classDeclaration);
-
- var changeBuilder = _newDartChangeBuilder();
- if (flutter.isExactlyStatelessWidgetType(superType) ||
- flutter.isExactlyStatefulWidgetType(superType)) {
- // Specialize for Flutter widgets.
- var keyClass = await sessionHelper.getClass(flutter.widgetsUri, 'Key');
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
- builder.write(targetLocation.prefix);
- builder.write('const ');
- builder.write(className);
- builder.write('({');
- builder.writeType(
- keyClass.instantiate(
- typeArguments: const [],
- nullabilitySuffix: _isNonNullable
- ? NullabilitySuffix.question
- : NullabilitySuffix.star,
- ),
- );
- builder.write(' key');
-
- var childrenFields = <String>[];
- for (var fieldName in fieldNames) {
- if (fieldName == 'child' || fieldName == 'children') {
- childrenFields.add(fieldName);
- continue;
- }
- builder.write(', this.');
- builder.write(fieldName);
- }
- for (var fieldName in childrenFields) {
- builder.write(', this.');
- builder.write(fieldName);
- }
-
- builder.write('}) : super(key: key);');
- builder.write(targetLocation.suffix);
- });
- });
- } else {
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
- builder.write(targetLocation.prefix);
- builder.writeConstructorDeclaration(className,
- fieldNames: fieldNames);
- builder.write(targetLocation.suffix);
- });
- });
- }
- _addFixFromBuilder(
- changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
- }
-
Future<void> _addFix_createConstructor_insteadOfSyntheticDefault() async {
if (node is! ArgumentList) {
return;
@@ -1714,92 +1507,6 @@
}
}
- Future<void> _addFix_createGetter() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier nameNode = node;
- var name = nameNode.name;
- if (!nameNode.inGetterContext()) {
- return;
- }
- // prepare target
- Expression target;
- {
- var nameParent = nameNode.parent;
- if (nameParent is PrefixedIdentifier) {
- target = nameParent.prefix;
- } else if (nameParent is PropertyAccess) {
- target = nameParent.realTarget;
- }
- }
- // prepare target element
- var staticModifier = false;
- Element targetElement;
- if (target is ExtensionOverride) {
- targetElement = target.staticElement;
- } else if (target is Identifier &&
- target.staticElement is ExtensionElement) {
- targetElement = target.staticElement;
- staticModifier = true;
- } else if (target != null) {
- // prepare target interface type
- var targetType = target.staticType;
- if (targetType is! InterfaceType) {
- return;
- }
- targetElement = targetType.element;
- // maybe static
- if (target is Identifier) {
- var targetIdentifier = target;
- var targetElement = targetIdentifier.staticElement;
- staticModifier = targetElement?.kind == ElementKind.CLASS;
- }
- } else {
- targetElement =
- getEnclosingClassElement(node) ?? getEnclosingExtensionElement(node);
- if (targetElement == null) {
- return;
- }
- staticModifier = _inStaticContext();
- }
- if (targetElement.librarySource.isInSystemLibrary) {
- return;
- }
- // prepare target declaration
- var targetDeclarationResult =
- await sessionHelper.getElementDeclaration(targetElement);
- if (targetDeclarationResult == null) {
- return;
- }
- if (targetDeclarationResult.node is! ClassOrMixinDeclaration &&
- targetDeclarationResult.node is! ExtensionDeclaration) {
- return;
- }
- CompilationUnitMember targetNode = targetDeclarationResult.node;
- // prepare location
- var targetLocation = CorrectionUtils(targetDeclarationResult.resolvedUnit)
- .prepareNewGetterLocation(targetNode);
- // build method source
- var targetSource = targetElement.source;
- var targetFile = targetSource.fullName;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) {
- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
- var fieldTypeNode = climbPropertyAccess(nameNode);
- var fieldType = _inferUndefinedExpressionType(fieldTypeNode);
- builder.write(targetLocation.prefix);
- builder.writeGetterDeclaration(name,
- isStatic: staticModifier,
- nameGroupName: 'NAME',
- returnType: fieldType,
- returnTypeGroupName: 'TYPE');
- builder.write(targetLocation.suffix);
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_GETTER, args: [name]);
- }
-
Future<void> _addFix_createImportUri() async {
// TODO(brianwilkerson) Generalize this to allow other valid string literals.
// TODO(brianwilkerson) Support the case where the node's parent is a Configuration.
@@ -1823,53 +1530,6 @@
}
}
- Future<void> _addFix_createLocalVariable() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier nameNode = node;
- var name = nameNode.name;
- // if variable is assigned, convert assignment into declaration
- if (node.parent is AssignmentExpression) {
- AssignmentExpression assignment = node.parent;
- if (assignment.leftHandSide == node &&
- assignment.operator.type == TokenType.EQ &&
- assignment.parent is ExpressionStatement) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(node.offset, 'var ');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_LOCAL_VARIABLE,
- args: [name]);
- return;
- }
- }
- // prepare target Statement
- var target = node.thisOrAncestorOfType<Statement>();
- if (target == null) {
- return;
- }
- var prefix = utils.getNodePrefix(target);
- // compute type
- var type = _inferUndefinedExpressionType(node);
- if (!(type == null || type is InterfaceType || type is FunctionType)) {
- return;
- }
- // build variable declaration source
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(target.offset, (DartEditBuilder builder) {
- builder.writeLocalVariableDeclaration(name,
- nameGroupName: 'NAME', type: type, typeGroupName: 'TYPE');
- builder.write(eol);
- builder.write(prefix);
- });
- builder.addLinkedPosition(range.node(node), 'NAME');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_LOCAL_VARIABLE,
- args: [name]);
- }
-
Future<void> _addFix_createMethod() async {
if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
return;
@@ -1964,198 +1624,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]);
}
- Future<void> _addFix_createMissingOverrides() async {
- if (node.parent is! ClassDeclaration) {
- return;
- }
- var targetClass = node.parent as ClassDeclaration;
- var targetClassElement = targetClass.declaredElement;
- utils.targetClassElement = targetClassElement;
- var signatures =
- InheritanceOverrideVerifier.missingOverrides(targetClass).toList();
- // sort by name, getters before setters
- signatures.sort((ExecutableElement a, ExecutableElement b) {
- var names = compareStrings(a.displayName, b.displayName);
- if (names != 0) {
- return names;
- }
- if (a.kind == ElementKind.GETTER) {
- return -1;
- }
- return 1;
- });
- var numElements = signatures.length;
-
- var location =
- utils.prepareNewClassMemberLocation(targetClass, (_) => true);
-
- var prefix = utils.getIndent(1);
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(location.offset, (DartEditBuilder builder) {
- // Separator management.
- var numOfMembersWritten = 0;
- void addSeparatorBetweenDeclarations() {
- if (numOfMembersWritten == 0) {
- builder.write(location.prefix);
- } else {
- builder.write(eol); // after the previous member
- builder.write(eol); // empty line separator
- builder.write(prefix);
- }
- numOfMembersWritten++;
- }
-
- // merge getter/setter pairs into fields
- for (var i = 0; i < signatures.length; i++) {
- var element = signatures[i];
- if (element.kind == ElementKind.GETTER && i + 1 < signatures.length) {
- var nextElement = signatures[i + 1];
- if (nextElement.kind == ElementKind.SETTER) {
- // remove this and the next elements, adjust iterator
- signatures.removeAt(i + 1);
- signatures.removeAt(i);
- i--;
- numElements--;
- // separator
- addSeparatorBetweenDeclarations();
- // @override
- builder.write('@override');
- builder.write(eol);
- // add field
- builder.write(prefix);
- builder.writeType(element.returnType, required: true);
- builder.write(' ');
- builder.write(element.name);
- builder.write(';');
- }
- }
- }
- // add elements
- for (var element in signatures) {
- addSeparatorBetweenDeclarations();
- builder.writeOverride(element);
- }
- builder.write(location.suffix);
- });
- });
- changeBuilder.setSelection(Position(file, location.offset));
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MISSING_OVERRIDES,
- args: [numElements]);
- }
-
- Future<void> _addFix_createMixin() async {
- Element prefixElement;
- String name;
- SimpleIdentifier nameNode;
- if (node is SimpleIdentifier) {
- var parent = node.parent;
- if (parent is PrefixedIdentifier) {
- if (parent.parent is InstanceCreationExpression) {
- return;
- }
- PrefixedIdentifier prefixedIdentifier = parent;
- prefixElement = prefixedIdentifier.prefix.staticElement;
- if (prefixElement == null) {
- return;
- }
- parent = prefixedIdentifier.parent;
- nameNode = prefixedIdentifier.identifier;
- name = prefixedIdentifier.identifier.name;
- } else if (parent is TypeName &&
- parent.parent is ConstructorName &&
- parent.parent.parent is InstanceCreationExpression) {
- return;
- } else {
- nameNode = node;
- name = nameNode.name;
- }
- if (!_mayBeTypeIdentifier(nameNode)) {
- return;
- }
- } else {
- return;
- }
- // prepare environment
- Element targetUnit;
- var prefix = '';
- var suffix = '';
- var offset = -1;
- String filePath;
- if (prefixElement == null) {
- targetUnit = unit.declaredElement;
- var enclosingMember = node.thisOrAncestorMatching((node) =>
- node is CompilationUnitMember && node.parent is CompilationUnit);
- if (enclosingMember == null) {
- return;
- }
- offset = enclosingMember.end;
- filePath = file;
- prefix = '$eol$eol';
- } else {
- for (var import in unitLibraryElement.imports) {
- if (prefixElement is PrefixElement && import.prefix == prefixElement) {
- var library = import.importedLibrary;
- if (library != null) {
- targetUnit = library.definingCompilationUnit;
- var targetSource = targetUnit.source;
- try {
- offset = targetSource.contents.data.length;
- filePath = targetSource.fullName;
- prefix = '$eol';
- suffix = '$eol';
- } on FileSystemException {
- // If we can't read the file to get the offset, then we can't
- // create a fix.
- }
- break;
- }
- }
- }
- }
- if (offset < 0) {
- return;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(filePath, (DartFileEditBuilder builder) {
- builder.addInsertion(offset, (DartEditBuilder builder) {
- builder.write(prefix);
- builder.writeMixinDeclaration(name, nameGroupName: 'NAME');
- builder.write(suffix);
- });
- if (prefixElement == null) {
- builder.addLinkedPosition(range.node(node), 'NAME');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MIXIN, args: [name]);
- }
-
- Future<void> _addFix_createNoSuchMethod() async {
- if (node.parent is! ClassDeclaration) {
- return;
- }
- var targetClass = node.parent as ClassDeclaration;
- // prepare environment
- var prefix = utils.getIndent(1);
- var insertOffset = targetClass.end - 1;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addInsertion(insertOffset, (DartEditBuilder builder) {
- builder.selectHere();
- // insert empty line before existing member
- if (targetClass.members.isNotEmpty) {
- builder.write(eol);
- }
- // append method
- builder.write(prefix);
- builder.write(
- 'noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);');
- builder.write(eol);
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_NO_SUCH_METHOD);
- }
-
Future<void> _addFix_createPartUri() async {
// TODO(brianwilkerson) Generalize this to allow other valid string literals.
if (node is SimpleStringLiteral && node.parent is PartDirective) {
@@ -2175,123 +1643,6 @@
}
}
- Future<void> _addFix_createSetter() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier nameNode = node;
- if (!nameNode.inSetterContext()) {
- return;
- }
- // prepare target
- Expression target;
- {
- var nameParent = nameNode.parent;
- if (nameParent is PrefixedIdentifier) {
- target = nameParent.prefix;
- } else if (nameParent is PropertyAccess) {
- target = nameParent.realTarget;
- }
- }
- // prepare target element
- var staticModifier = false;
- Element targetElement;
- if (target is ExtensionOverride) {
- targetElement = target.staticElement;
- } else if (target is Identifier &&
- target.staticElement is ExtensionElement) {
- targetElement = target.staticElement;
- staticModifier = true;
- } else if (target != null) {
- // prepare target interface type
- var targetType = target.staticType;
- if (targetType is! InterfaceType) {
- return;
- }
- targetElement = targetType.element;
- // maybe static
- if (target is Identifier) {
- var targetIdentifier = target;
- var targetElement = targetIdentifier.staticElement;
- staticModifier = targetElement?.kind == ElementKind.CLASS;
- }
- } else {
- targetElement =
- getEnclosingClassElement(node) ?? getEnclosingExtensionElement(node);
- if (targetElement == null) {
- return;
- }
- staticModifier = _inStaticContext();
- }
- if (targetElement.librarySource.isInSystemLibrary) {
- return;
- }
- // prepare target declaration
- var targetDeclarationResult =
- await sessionHelper.getElementDeclaration(targetElement);
- if (targetDeclarationResult == null) {
- return;
- }
- if (targetDeclarationResult.node is! ClassOrMixinDeclaration &&
- targetDeclarationResult.node is! ExtensionDeclaration) {
- return;
- }
- CompilationUnitMember targetNode = targetDeclarationResult.node;
- // prepare location
- var targetLocation = CorrectionUtils(targetDeclarationResult.resolvedUnit)
- .prepareNewGetterLocation(targetNode); // Rename to "AccessorLocation"
- // build method source
- var targetSource = targetElement.source;
- var targetFile = targetSource.fullName;
- var name = nameNode.name;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) {
- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
- var parameterTypeNode = climbPropertyAccess(nameNode);
- var parameterType = _inferUndefinedExpressionType(parameterTypeNode);
- builder.write(targetLocation.prefix);
- builder.writeSetterDeclaration(name,
- isStatic: staticModifier,
- nameGroupName: 'NAME',
- parameterType: parameterType,
- parameterTypeGroupName: 'TYPE');
- builder.write(targetLocation.suffix);
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_SETTER, args: [name]);
- }
-
- Future<void> _addFix_extendClassForMixin() async {
- var declaration = node.thisOrAncestorOfType<ClassDeclaration>();
- if (declaration != null && declaration.extendsClause == null) {
- // TODO(brianwilkerson) Find a way to pass in the name of the class
- // without needing to parse the message.
- var message = error.message;
- var endIndex = message.lastIndexOf("'");
- var startIndex = message.lastIndexOf("'", endIndex - 1) + 1;
- var typeName = message.substring(startIndex, endIndex);
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(
- declaration.typeParameters?.end ?? declaration.name.end,
- ' extends $typeName');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.EXTEND_CLASS_FOR_MIXIN,
- args: [typeName]);
- }
- }
-
- Future<void> _addFix_illegalAsyncReturnType() async {
- // prepare the existing type
- var typeName = node.thisOrAncestorOfType<TypeAnnotation>();
- var typeProvider = this.typeProvider;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.replaceTypeWithFuture(typeName, typeProvider);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
- }
-
Future<void> _addFix_importAsync() async {
await _addFix_importLibrary(
DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async'));
@@ -2476,487 +1827,6 @@
}
}
- Future<void> _addFix_insertSemicolon() async {
- if (error.message.contains("';'")) {
- if (_isAwaitNode()) {
- return;
- }
- var insertOffset = error.offset + error.length;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(insertOffset, ';');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.INSERT_SEMICOLON);
- }
- }
-
- Future<void> _addFix_isNotNull() async {
- if (coveredNode is IsExpression) {
- var isExpression = coveredNode as IsExpression;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder
- .addReplacement(range.endEnd(isExpression.expression, isExpression),
- (DartEditBuilder builder) {
- builder.write(' != null');
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.USE_NOT_EQ_NULL);
- }
- }
-
- Future<void> _addFix_isNull() async {
- if (coveredNode is IsExpression) {
- var isExpression = coveredNode as IsExpression;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder
- .addReplacement(range.endEnd(isExpression.expression, isExpression),
- (DartEditBuilder builder) {
- builder.write(' == null');
- });
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.USE_EQ_EQ_NULL);
- }
- }
-
- Future<void> _addFix_makeEnclosingClassAbstract() async {
- var enclosingClass = node.thisOrAncestorOfType<ClassDeclaration>();
- if (enclosingClass == null) {
- return;
- }
- var className = enclosingClass.name.name;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(
- enclosingClass.classKeyword.offset, 'abstract ');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_CLASS_ABSTRACT,
- args: [className]);
- }
-
- Future<void> _addFix_makeFieldNotFinal() async {
- var node = this.node;
- if (node is SimpleIdentifier &&
- node.staticElement is PropertyAccessorElement) {
- PropertyAccessorElement getter = node.staticElement;
- if (getter.isGetter &&
- getter.isSynthetic &&
- !getter.variable.isSynthetic &&
- getter.variable.setter == null &&
- getter.enclosingElement is ClassElement) {
- var declarationResult =
- await sessionHelper.getElementDeclaration(getter.variable);
- var variable = declarationResult.node;
- if (variable is VariableDeclaration &&
- variable.parent is VariableDeclarationList &&
- variable.parent.parent is FieldDeclaration) {
- VariableDeclarationList declarationList = variable.parent;
- var keywordToken = declarationList.keyword;
- if (declarationList.variables.length == 1 &&
- keywordToken.keyword == Keyword.FINAL) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file,
- (DartFileEditBuilder builder) {
- if (declarationList.type != null) {
- builder.addReplacement(
- range.startStart(keywordToken, declarationList.type),
- (DartEditBuilder builder) {});
- } else {
- builder.addReplacement(range.startStart(keywordToken, variable),
- (DartEditBuilder builder) {
- builder.write('var ');
- });
- }
- });
- var fieldName = getter.variable.displayName;
- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_FIELD_NOT_FINAL,
- args: [fieldName]);
- }
- }
- }
- }
- }
-
- Future<void> _addFix_makeVariableNotFinal() async {
- var node = this.node;
- if (node is SimpleIdentifier &&
- node.staticElement is LocalVariableElement) {
- LocalVariableElement variable = node.staticElement;
- var id = NodeLocator(variable.nameOffset).searchWithin(unit);
- var decl = id?.parent;
- if (decl is VariableDeclaration &&
- decl.parent is VariableDeclarationList) {
- VariableDeclarationList declarationList = decl.parent;
- var keywordToken = declarationList.keyword;
- if (declarationList.variables.length == 1 &&
- keywordToken.keyword == Keyword.FINAL) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (declarationList.type != null) {
- builder.addDeletion(
- range.startStart(keywordToken, declarationList.type));
- } else {
- builder.addSimpleReplacement(range.token(keywordToken), 'var');
- }
- });
- declarationList.variables[0].name.name;
- var varName = declarationList.variables[0].name.name;
- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_VARIABLE_NOT_FINAL,
- args: [varName]);
- }
- }
- }
- }
-
- Future<void> _addFix_moveTypeArgumentsToClass() async {
- if (coveredNode is TypeArgumentList) {
- TypeArgumentList typeArguments = coveredNode;
- if (typeArguments.parent is! InstanceCreationExpression) {
- return;
- }
- InstanceCreationExpression creation = typeArguments.parent;
- var typeName = creation.constructorName.type;
- if (typeName.typeArguments != null) {
- return;
- }
- var element = typeName.type.element;
- if (element is ClassElement &&
- element.typeParameters != null &&
- element.typeParameters.length == typeArguments.arguments.length) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var argumentText = utils.getNodeText(typeArguments);
- builder.addSimpleInsertion(typeName.end, argumentText);
- builder.addDeletion(range.node(typeArguments));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
- }
- }
- }
-
- Future<void> _addFix_nonBoolCondition_addNotNull() async {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(error.offset + error.length, ' != null');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL);
- }
-
- Future<void> _addFix_qualifyReference() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- SimpleIdentifier memberName = node;
- var parent = node.parent;
- AstNode target;
- if (parent is MethodInvocation && node == parent.methodName) {
- target = parent.target;
- } else if (parent is PropertyAccess && node == parent.propertyName) {
- target = parent.target;
- }
- if (target != null) {
- return;
- }
- var enclosingElement = memberName.staticElement.enclosingElement;
- if (enclosingElement.library != unitLibraryElement) {
- // TODO(brianwilkerson) Support qualifying references to members defined
- // in other libraries. `DartEditBuilder` currently defines the method
- // `writeType`, which is close, but we also need to handle extensions,
- // which don't have a type.
- return;
- }
- var containerName = enclosingElement.name;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(node.offset, '$containerName.');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.QUALIFY_REFERENCE,
- args: ['$containerName.${memberName.name}']);
- }
-
- Future<void> _addFix_removeAnnotation() async {
- void addFix(Annotation node) async {
- if (node == null) {
- return;
- }
- var followingToken = node.endToken.next;
- followingToken = followingToken.precedingComments ?? followingToken;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(node, followingToken));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_ANNOTATION,
- args: [node.name.name]);
- }
-
- Annotation findAnnotation(
- NodeList<Annotation> metadata, String targetName) {
- return metadata.firstWhere(
- (annotation) => annotation.name.name == targetName,
- orElse: () => null);
- }
-
- var node = coveredNode;
- if (node is Annotation) {
- await addFix(node);
- } else if (node is DefaultFormalParameter) {
- await addFix(findAnnotation(node.parameter.metadata, 'required'));
- } else if (node is NormalFormalParameter) {
- await addFix(findAnnotation(node.metadata, 'required'));
- } else if (node is DeclaredSimpleIdentifier) {
- var parent = node.parent;
- if (parent is MethodDeclaration) {
- await addFix(findAnnotation(parent.metadata, 'override'));
- } else if (parent is VariableDeclaration) {
- var fieldDeclaration = parent.thisOrAncestorOfType<FieldDeclaration>();
- if (fieldDeclaration != null) {
- await addFix(findAnnotation(fieldDeclaration.metadata, 'override'));
- }
- }
- }
- }
-
- Future<void> _addFix_removeDeadCode() async {
- var coveringNode = coveredNode;
- if (coveringNode is Expression) {
- var parent = coveredNode.parent;
- if (parent is BinaryExpression) {
- if (parent.rightOperand == coveredNode) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.endEnd(parent.leftOperand, coveredNode));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
- }
- }
- } else if (coveringNode is Block) {
- var block = coveringNode;
- var statementsToRemove = <Statement>[];
- var errorRange = SourceRange(errorOffset, errorLength);
- for (var statement in block.statements) {
- if (range.node(statement).intersects(errorRange)) {
- statementsToRemove.add(statement);
- }
- }
- if (statementsToRemove.isNotEmpty) {
- var rangeToRemove = utils.getLinesRangeStatements(statementsToRemove);
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(rangeToRemove);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
- }
- } else if (coveringNode is Statement) {
- var rangeToRemove =
- utils.getLinesRangeStatements(<Statement>[coveringNode]);
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(rangeToRemove);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
- } else if (coveringNode is CatchClause) {
- TryStatement tryStatement = coveringNode.parent;
- var catchClauses = tryStatement.catchClauses;
- var index = catchClauses.indexOf(coveringNode);
- var previous = index == 0 ? tryStatement.body : catchClauses[index - 1];
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.endEnd(previous, coveringNode));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
- }
- }
-
- Future<void> _addFix_removeNameFromCombinator() async {
- SourceRange rangeForCombinator(Combinator combinator) {
- var parent = combinator.parent;
- if (parent is NamespaceDirective) {
- var combinators = parent.combinators;
- if (combinators.length == 1) {
- var previousToken =
- combinator.parent.findPrevious(combinator.beginToken);
- if (previousToken != null) {
- return range.endEnd(previousToken, combinator);
- }
- return null;
- }
- var index = combinators.indexOf(combinator);
- if (index < 0) {
- return null;
- } else if (index == combinators.length - 1) {
- return range.endEnd(combinators[index - 1], combinator);
- }
- return range.startStart(combinator, combinators[index + 1]);
- }
- return null;
- }
-
- SourceRange rangeForNameInCombinator(
- Combinator combinator, SimpleIdentifier name) {
- NodeList<SimpleIdentifier> names;
- if (combinator is HideCombinator) {
- names = combinator.hiddenNames;
- } else if (combinator is ShowCombinator) {
- names = combinator.shownNames;
- } else {
- return null;
- }
- if (names.length == 1) {
- return rangeForCombinator(combinator);
- }
- var index = names.indexOf(name);
- if (index < 0) {
- return null;
- } else if (index == names.length - 1) {
- return range.endEnd(names[index - 1], name);
- }
- return range.startStart(name, names[index + 1]);
- }
-
- var node = coveredNode;
- if (node is SimpleIdentifier) {
- var parent = coveredNode.parent;
- if (parent is Combinator) {
- var rangeToRemove = rangeForNameInCombinator(parent, node);
- if (rangeToRemove == null) {
- return;
- }
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(rangeToRemove);
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_NAME_FROM_COMBINATOR,
- args: [parent is HideCombinator ? 'hide' : 'show']);
- }
- }
- }
-
- Future<void> _addFix_removeParameters_inGetterDeclaration() async {
- if (node is MethodDeclaration) {
- // Support for the analyzer error.
- var method = node as MethodDeclaration;
- var name = method.name;
- var body = method.body;
- if (name != null && body != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(range.endStart(name, body), ' ');
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION);
- }
- } else if (node is FormalParameterList) {
- // Support for the fasta error.
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.node(node));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION);
- }
- }
-
- Future<void> _addFix_removeParentheses_inGetterInvocation() async {
- var invocation = coveredNode?.parent;
- if (invocation is FunctionExpressionInvocation) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.node(invocation.argumentList));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION);
- }
- }
-
- Future<void> _addFix_removeTypeArguments() async {
- if (coveredNode is TypeArgumentList) {
- TypeArgumentList typeArguments = coveredNode;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.node(typeArguments));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_ARGUMENTS);
- }
- }
-
- Future<void> _addFix_removeUnnecessaryCast() async {
- if (coveredNode is! AsExpression) {
- return;
- }
- var asExpression = coveredNode as AsExpression;
- var expression = asExpression.expression;
- var expressionPrecedence = getExpressionPrecedence(expression);
- // remove 'as T' from 'e as T'
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.endEnd(expression, asExpression));
- _removeEnclosingParentheses(builder, asExpression, expressionPrecedence);
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNNECESSARY_CAST);
- }
-
- Future<void> _addFix_removeUnusedCatchClause() async {
- if (node is SimpleIdentifier) {
- var catchClause = node.parent;
- if (catchClause is CatchClause &&
- catchClause.exceptionParameter == node) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(
- range.startStart(catchClause.catchKeyword, catchClause.body));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE);
- }
- }
- }
-
- Future<void> _addFix_removeUnusedCatchStack() async {
- if (node is SimpleIdentifier) {
- var catchClause = node.parent;
- if (catchClause is CatchClause &&
- catchClause.stackTraceParameter == node &&
- catchClause.exceptionParameter != null) {
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder
- .addDeletion(range.endEnd(catchClause.exceptionParameter, node));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_STACK);
- }
- }
- }
-
- Future<void> _addFix_removeUnusedImport() async {
- // prepare ImportDirective
- var importDirective = node.thisOrAncestorOfType<ImportDirective>();
- if (importDirective == null) {
- return;
- }
- // remove the whole line with import
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(utils.getLinesRange(range.node(importDirective)));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT);
- }
-
- Future<void> _addFix_removeUnusedLabel() async {
- final parent = node.parent;
- if (parent is Label) {
- var nextToken = parent.endToken.next;
- final changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addDeletion(range.startStart(parent, nextToken));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_LABEL);
- }
- }
-
Future<void> _addFix_replaceVarWithDynamic() async {
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -2965,47 +1835,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_VAR_WITH_DYNAMIC);
}
- Future<void> _addFix_replaceWithConstInstanceCreation() async {
- if (coveredNode is InstanceCreationExpression) {
- var instanceCreation = coveredNode as InstanceCreationExpression;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (instanceCreation.keyword == null) {
- builder.addSimpleInsertion(
- instanceCreation.constructorName.offset, 'const');
- } else {
- builder.addSimpleReplacement(
- range.token(instanceCreation.keyword), 'const');
- }
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.USE_CONST);
- }
- }
-
- Future<void> _addFix_replaceWithExtensionName() async {
- if (node is! SimpleIdentifier) {
- return;
- }
- var parent = node.parent;
- AstNode target;
- if (parent is MethodInvocation && node == parent.methodName) {
- target = parent.target;
- } else if (parent is PropertyAccess && node == parent.propertyName) {
- target = parent.target;
- }
- if (target is! ExtensionOverride) {
- return;
- }
- ExtensionOverride override = target;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleReplacement(
- range.node(override), utils.getNodeText(override.extensionName));
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_EXTENSION_NAME,
- args: [override.extensionName.name]);
- }
-
Future<void> _addFix_undefinedClass_useSimilar() async {
var node = this.node;
// Prepare the optional import prefix name.
@@ -3268,68 +2097,6 @@
_addFixFromBuilder(changeBuilder, DartFixKind.UPDATE_SDK_CONSTRAINTS);
}
- Future<void> _addFix_useEffectiveIntegerDivision() async {
- for (var n = node; n != null; n = n.parent) {
- if (n is MethodInvocation &&
- n.offset == errorOffset &&
- n.length == errorLength) {
- var target = (n as MethodInvocation).target.unParenthesized;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- // replace "/" with "~/"
- var binary = target as BinaryExpression;
- builder.addSimpleReplacement(range.token(binary.operator), '~/');
- // remove everything before and after
- builder.addDeletion(range.startStart(n, binary.leftOperand));
- builder.addDeletion(range.endEnd(binary.rightOperand, n));
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION);
- // done
- break;
- }
- }
- }
-
- /// Adds a fix that replaces [target] with a reference to the class declaring
- /// the given [element].
- Future<void> _addFix_useStaticAccess(AstNode target, Element element) async {
- var declaringElement = element.enclosingElement;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(range.node(target), (DartEditBuilder builder) {
- builder.writeReference(declaringElement);
- });
- });
- _addFixFromBuilder(
- changeBuilder,
- DartFixKind.CHANGE_TO_STATIC_ACCESS,
- args: [declaringElement.name],
- );
- }
-
- Future<void> _addFix_useStaticAccess_method() async {
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- var invocation = node.parent as MethodInvocation;
- if (invocation.methodName == node) {
- var target = invocation.target;
- var invokedElement = invocation.methodName.staticElement;
- await _addFix_useStaticAccess(target, invokedElement);
- }
- }
- }
-
- Future<void> _addFix_useStaticAccess_property() async {
- if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) {
- var prefixed = node.parent as PrefixedIdentifier;
- if (prefixed.identifier == node) {
- Expression target = prefixed.prefix;
- var invokedElement = prefixed.identifier.staticElement;
- await _addFix_useStaticAccess(target, invokedElement);
- }
- }
- }
-
void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
{List<Object> args, bool importsOnly = false}) {
if (builder == null) return;
@@ -3687,11 +2454,6 @@
return method != null && method.isStatic;
}
- bool _isAwaitNode() {
- var node = this.node;
- return node is SimpleIdentifier && node.name == 'await';
- }
-
bool _isLibSrcPath(String path) {
var parts = resourceProvider.pathContext.split(path);
for (var i = 0; i < parts.length - 2; i++) {
@@ -3706,22 +2468,6 @@
return DartChangeBuilderImpl.forWorkspace(context.workspace);
}
- /// Removes any [ParenthesizedExpression] enclosing [expr].
- ///
- /// [exprPrecedence] - the effective precedence of [expr].
- void _removeEnclosingParentheses(
- DartFileEditBuilder builder, Expression expr, Precedence exprPrecedence) {
- while (expr.parent is ParenthesizedExpression) {
- var parenthesized = expr.parent as ParenthesizedExpression;
- if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) {
- break;
- }
- builder.addDeletion(range.token(parenthesized.leftParenthesis));
- builder.addDeletion(range.token(parenthesized.rightParenthesis));
- expr = parenthesized;
- }
- }
-
void _updateFinderWithClassMembers(
_ClosestElementFinder finder, ClassElement clazz) {
if (clazz != null) {
@@ -3812,80 +2558,3 @@
}
}
}
-
-/// [ExecutableElement], its parameters, and operations on them.
-class _ExecutableParameters {
- final AnalysisSessionHelper sessionHelper;
- final ExecutableElement executable;
-
- final List<ParameterElement> required = [];
- final List<ParameterElement> optionalPositional = [];
- final List<ParameterElement> named = [];
-
- factory _ExecutableParameters(
- AnalysisSessionHelper sessionHelper, AstNode invocation) {
- Element element;
- // This doesn't handle FunctionExpressionInvocation.
- if (invocation is Annotation) {
- element = invocation.element;
- } else if (invocation is InstanceCreationExpression) {
- element = invocation.staticElement;
- } else if (invocation is MethodInvocation) {
- element = invocation.methodName.staticElement;
- } else if (invocation is ConstructorReferenceNode) {
- element = invocation.staticElement;
- }
- if (element is ExecutableElement && !element.isSynthetic) {
- return _ExecutableParameters._(sessionHelper, element);
- } else {
- return null;
- }
- }
-
- _ExecutableParameters._(this.sessionHelper, this.executable) {
- for (var parameter in executable.parameters) {
- if (parameter.isRequiredPositional) {
- required.add(parameter);
- } else if (parameter.isOptionalPositional) {
- optionalPositional.add(parameter);
- } else if (parameter.isNamed) {
- named.add(parameter);
- }
- }
- }
-
- String get file => executable.source.fullName;
-
- List<String> get namedNames {
- return named.map((parameter) => parameter.name).toList();
- }
-
- /// Return the [FormalParameterList] of the [executable], or `null` is cannot
- /// be found.
- Future<FormalParameterList> getParameterList() async {
- var result = await sessionHelper.getElementDeclaration(executable);
- var targetDeclaration = result.node;
- if (targetDeclaration is ConstructorDeclaration) {
- return targetDeclaration.parameters;
- } else if (targetDeclaration is FunctionDeclaration) {
- var function = targetDeclaration.functionExpression;
- return function.parameters;
- } else if (targetDeclaration is MethodDeclaration) {
- return targetDeclaration.parameters;
- }
- return null;
- }
-
- /// Return the [FormalParameter] of the [element] in [FormalParameterList],
- /// or `null` is cannot be found.
- Future<FormalParameter> getParameterNode(ParameterElement element) async {
- var result = await sessionHelper.getElementDeclaration(element);
- var declaration = result.node;
- for (var node = declaration; node != null; node = node.parent) {
- if (node is FormalParameter && node.parent is FormalParameterList) {
- return node;
- }
- }
- return null;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/flutter/property.dart b/pkg/analysis_server/lib/src/services/flutter/property.dart
index a031ac7..427141a 100644
--- a/pkg/analysis_server/lib/src/services/flutter/property.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/property.dart
@@ -432,7 +432,7 @@
Expression bottomExpression;
var propertyExpression = property.valueExpression;
if (propertyExpression is InstanceCreationExpression) {
- var constructor = propertyExpression.staticElement;
+ var constructor = propertyExpression.constructorName.staticElement;
if (constructor?.enclosingElement == classEdgeInsets) {
var arguments = propertyExpression.argumentList.arguments;
if (constructor.name == 'all') {
diff --git a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
index 65769b0..174a9a2 100644
--- a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
@@ -152,7 +152,7 @@
return null;
}
- var constructorElement = instanceCreation.staticElement;
+ var constructorElement = instanceCreation.constructorName.staticElement;
if (constructorElement == null) {
return null;
}
@@ -267,7 +267,7 @@
InstanceCreationExpression instanceCreation,
ConstructorElement constructorElement,
}) {
- constructorElement ??= instanceCreation?.staticElement;
+ constructorElement ??= instanceCreation?.constructorName?.staticElement;
constructorElement ??= classDescription?.constructor;
if (constructorElement == null) return;
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 187c91b..804b6b5 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -27,6 +27,8 @@
'avoid_types_as_parameter_names';
static const String avoid_types_on_closure_parameters =
'avoid_types_on_closure_parameters';
+ static const String avoid_unused_constructor_parameters =
+ 'avoid_unused_constructor_parameters';
static const String await_only_futures = 'await_only_futures';
static const String curly_braces_in_flow_control_structures =
'curly_braces_in_flow_control_structures';
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 6d9bbf2..29a96b8 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -95,7 +95,6 @@
properties['static element'] = node.staticElement;
properties['static type'] = node.staticType;
} else if (node is InstanceCreationExpression) {
- properties['static element'] = node.staticElement;
properties['static type'] = node.staticType;
} else if (node is LibraryDirective) {
properties['element'] = node.element;
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index 08c9469ab..0a9b690 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -247,7 +247,7 @@
/// Return the presentation for the given Flutter `Widget` creation [node].
String getWidgetPresentationText(InstanceCreationExpression node) {
- var element = node.staticElement?.enclosingElement;
+ var element = node.constructorName.staticElement?.enclosingElement;
if (!isWidget(element)) {
return null;
}
@@ -524,7 +524,7 @@
/// Return `true` if the given [expr] is a constructor invocation for a
/// class that has the Flutter class `Widget` as a superclass.
bool isWidgetCreation(InstanceCreationExpression expr) {
- var element = expr?.staticElement?.enclosingElement;
+ var element = expr?.constructorName?.staticElement?.enclosingElement;
return isWidget(element);
}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
index cb7fff9..c73b71b 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
@@ -96,9 +96,10 @@
''');
// The order below is dependent on generated data, so it can validly change
// when the data is re-generated.
+ // Getters, setters and fields now all have the same relevance.
assertOrder([
suggestionWith(completion: 'g'),
- suggestionWith(completion: 's'),
+// suggestionWith(completion: 's'),
suggestionWith(completion: 'm'),
]);
}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
index d3a952e..a78beb0 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/static_member_relevance_test.dart
@@ -54,11 +54,14 @@
C.^
}
''');
+ // The order below is dependent on generated data, so it can validly change
+ // when the data is re-generated.
+ // Getters, setters and fields now all have the same relevance.
assertOrder([
- suggestionWith(completion: 'g'),
- suggestionWith(completion: 's'),
- suggestionWith(completion: 'm'),
+// suggestionWith(completion: 'g'),
+// suggestionWith(completion: 's'),
suggestionWith(completion: 'f'),
+ suggestionWith(completion: 'm'),
]);
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
index fd84462..0a9f0b2 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
@@ -54,6 +54,17 @@
await assertNoAssistAt('v;');
}
+ Future<void> test_instanceCreation_freeStanding() async {
+ await resolveTestUnit('''
+class A {}
+
+main() {
+ A();
+}
+''');
+ await assertNoAssistAt('A();');
+ }
+
Future<void> test_localVariable() async {
await resolveTestUnit('''
main() {
@@ -124,6 +135,23 @@
''');
}
+ Future<void> test_loopVariable_nested() async {
+ await resolveTestUnit('''
+main() {
+ var v = () {
+ for (int x in <int>[]) {}
+ };
+}
+''');
+ await assertHasAssistAt('int x', '''
+main() {
+ var v = () {
+ for (var x in <int>[]) {}
+ };
+}
+''');
+ }
+
Future<void> test_loopVariable_noType() async {
await resolveTestUnit('''
main() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
index ab9e0af..acc3551 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
@@ -10,12 +10,12 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ChangeToStaticAccessClassTest);
+ defineReflectiveTests(ChangeToStaticAccessTest);
});
}
@reflectiveTest
-class ChangeToStaticAccessClassTest extends FixProcessorTest {
+class ChangeToStaticAccessTest extends FixProcessorTest {
@override
FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
index 5a0c97c..eedea5b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
@@ -21,6 +21,23 @@
@override
FixKind get kind => DartFixKind.CREATE_CLASS;
+ Future<void> test_annotation() async {
+ await resolveTestUnit('''
+@Test('a')
+void f() {}
+''');
+ await assertHasFix('''
+@Test('a')
+void f() {}
+
+class Test {
+ const Test(String s);
+}
+''');
+ assertLinkedGroup(
+ change.linkedEditGroups[0], ["Test('", 'Test {', 'Test(S']);
+ }
+
Future<void> test_hasUnresolvedPrefix() async {
await resolveTestUnit('''
main() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index a86150d..e8ed56b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -539,9 +538,7 @@
import 'package:test/lib.dart';
class X = Object with Test;
-''', errorFilter: (error) {
- return error.errorCode == CompileTimeErrorCode.UNDEFINED_CLASS;
- });
+''');
}
Future<void> test_withTopLevelVariable() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart
new file mode 100644
index 0000000..1b691b3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_parameter_test.dart
@@ -0,0 +1,217 @@
+// 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';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedParameterTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedParameterTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_PARAMETER;
+
+ @override
+ String get lintCode => LintNames.avoid_unused_constructor_parameters;
+
+ Future<void> test_first_optionalNamed_second_optionalNamed() async {
+ await resolveTestUnit('''
+class C {
+ int y;
+ C({int x = 0, this.y = 0});
+}
+''');
+ await assertHasFix('''
+class C {
+ int y;
+ C({this.y = 0});
+}
+''');
+ }
+
+ Future<void> test_first_optionalPositional_second_optionalPositional() async {
+ await resolveTestUnit('''
+class C {
+ int y;
+ C([int x = 0, this.y = 0]);
+}
+''');
+ await assertHasFix('''
+class C {
+ int y;
+ C([this.y = 0]);
+}
+''');
+ }
+
+ Future<void> test_first_requiredPositional_second_optionalNamed() async {
+ await resolveTestUnit('''
+class C {
+ int y;
+ C(int x, {this.y = 0});
+}
+''');
+ await assertHasFix('''
+class C {
+ int y;
+ C({this.y = 0});
+}
+''');
+ }
+
+ Future<void> test_first_requiredPositional_second_optionalPositional() async {
+ await resolveTestUnit('''
+class C {
+ int y;
+ C(int x, [this.y = 0]);
+}
+''');
+ await assertHasFix('''
+class C {
+ int y;
+ C([this.y = 0]);
+}
+''');
+ }
+
+ Future<void> test_first_requiredPositional_second_requiredPositional() async {
+ await resolveTestUnit('''
+class C {
+ int y;
+ C(int x, this.y);
+}
+''');
+ await assertHasFix('''
+class C {
+ int y;
+ C(this.y);
+}
+''');
+ }
+
+ Future<void> test_last_optionalNamed_previous_optionalNamed() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+ C({this.x = 0, int y = 0});
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+ C({this.x = 0});
+}
+''');
+ }
+
+ Future<void> test_last_optionalNamed_previous_requiredPositional() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+ C(this.x, {int y = 0});
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+ C(this.x);
+}
+''');
+ }
+
+ Future<void>
+ test_last_optionalPositional_previous_optionalPositional() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+ C([this.x = 0, int y = 0]);
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+ C([this.x = 0]);
+}
+''');
+ }
+
+ Future<void>
+ test_last_optionalPositional_previous_requiredPositional() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+ C(this.x, [int y = 0]);
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+ C(this.x);
+}
+''');
+ }
+
+ Future<void>
+ test_last_requiredPositional_previous_requiredPositional() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+ C(this.x, int y);
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+ C(this.x);
+}
+''');
+ }
+
+ Future<void> test_only_optionalNamed() async {
+ await resolveTestUnit('''
+class C {
+ C({int x = 0});
+}
+''');
+ await assertHasFix('''
+class C {
+ C();
+}
+''');
+ }
+
+ Future<void> test_only_optionalPositional() async {
+ await resolveTestUnit('''
+class C {
+ C([int x = 0]);
+}
+''');
+ await assertHasFix('''
+class C {
+ C();
+}
+''');
+ }
+
+ Future<void> test_only_requiredPositional() async {
+ await resolveTestUnit('''
+class C {
+ C(int x);
+}
+''');
+ await assertHasFix('''
+class C {
+ C();
+}
+''');
+ }
+}
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 2c18bb7..736738d 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
@@ -126,6 +126,7 @@
import 'remove_unused_import_test.dart' as remove_unused_import;
import 'remove_unused_label_test.dart' as remove_unused_label;
import 'remove_unused_local_variable_test.dart' as remove_unused_local_variable;
+import 'remove_unused_parameter_test.dart' as remove_unused_parameter;
import 'rename_to_camel_case_test.dart' as rename_to_camel_case;
import 'replace_boolean_with_bool_test.dart' as replace_boolean_with_bool;
import 'replace_colon_with_equals_test.dart' as replace_colon_with_equals;
@@ -269,6 +270,7 @@
remove_unused_import.main();
remove_unused_label.main();
remove_unused_local_variable.main();
+ remove_unused_parameter.main();
rename_to_camel_case.main();
replace_boolean_with_bool.main();
replace_colon_with_equals.main();
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index 0f06e85..ceb6dd8 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -1516,7 +1516,7 @@
/// identifier that is a child of the [node].
ElementKind _leftMostKind(AstNode node) {
if (node is InstanceCreationExpression) {
- return convertElementToElementKind(node.staticElement);
+ return convertElementToElementKind(node.constructorName.staticElement);
}
var element = _leftMostElement(node);
if (element == null) {
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
index fed80b42..fb0bff8 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_table_generator.dart
@@ -6,8 +6,7 @@
import 'dart:io' as io;
import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart';
-import 'package:analysis_server/src/protocol_server.dart'
- show convertElementToElementKind, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart' show ElementKind;
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analysis_tool/tools.dart';
@@ -1276,7 +1275,8 @@
/// identifier that is a child of the [node].
ElementKind _leftMostKind(AstNode node) {
if (node is InstanceCreationExpression) {
- return convertElementToElementKind(node.staticElement);
+ return featureComputer
+ .computeElementKind(node.constructorName.staticElement);
}
var element = _leftMostElement(node);
if (element == null) {
@@ -1288,7 +1288,7 @@
element = parent.element;
}
}
- return convertElementToElementKind(element);
+ return featureComputer.computeElementKind(element);
}
/// Return the left-most token that is a child of the [node].
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 3c9232f..2de4989 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,8 @@
## 0.39.9-dev
* Deprecated `DartType.isObject`, use `DartType.isDartCoreObject` for
consistency with other similar getters.
+* Deprecated `InstanceCreationExpression.staticElement`, use
+ `constructorName.staticElement` instead, like for `MethodInvocation`.
## 0.39.8
* Deprecated `VariableElement.constantValue`, it does not guarantee that
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index a97a7b5..7fe19b3 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -3291,6 +3291,14 @@
/// Set the 'new' or 'const' keyword used to indicate how an object should be
/// created to the given [token].
set keyword(Token token);
+
+ @Deprecated('Use constructorName.staticElement')
+ @override
+ ConstructorElement get staticElement;
+
+ @Deprecated('Use constructorName.staticElement')
+ @override
+ set staticElement(ConstructorElement staticElement);
}
/// An integer literal expression.
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 7903c31..6d6db84 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -112,11 +112,7 @@
@override
Resource getResource(String path) {
_ensureAbsoluteAndNormalized(path);
- Resource resource = _pathToResource[path];
- if (resource == null) {
- resource = _MemoryFile(this, path);
- }
- return resource;
+ return _pathToResource[path] ?? _MemoryFile(this, path);
}
@override
@@ -517,11 +513,8 @@
@override
Resource getChild(String relPath) {
String childPath = canonicalizePath(relPath);
- _MemoryResource resource = _provider._pathToResource[childPath];
- if (resource == null) {
- resource = _MemoryFile(_provider, childPath);
- }
- return resource;
+ return _provider._pathToResource[childPath] ??
+ _MemoryFile(_provider, childPath);
}
@override
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 5d5bf1a..006e5f3 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -23,7 +23,6 @@
const String implicitCastsFlag = 'implicit-casts';
const String lintsFlag = 'lints';
const String noImplicitDynamicFlag = 'no-implicit-dynamic';
-const String packageRootOption = 'package-root';
const String packagesOption = 'packages';
const String sdkPathOption = 'dart-sdk';
@@ -69,7 +68,6 @@
builderOptions.defaultAnalysisOptionsFilePath =
args[analysisOptionsFileOption];
builderOptions.defaultPackageFilePath = args[packagesOption];
- builderOptions.defaultPackagesDirectoryPath = args[packageRootOption];
//
// Analysis options.
//
@@ -137,10 +135,6 @@
help: 'The path to the Dart SDK.', hide: ddc && hide);
parser.addOption(analysisOptionsFileOption,
help: 'Path to an analysis options file.', hide: ddc && hide);
- parser.addOption(packageRootOption,
- help: 'The path to a package root directory (deprecated). '
- 'This option cannot be used with --packages.',
- hide: ddc && hide);
parser.addFlag('strong',
help: 'Enable strong mode (deprecated); this option is now ignored.',
defaultsTo: true,
@@ -170,8 +164,7 @@
hide: hide);
parser.addOption(packagesOption,
help: 'The path to the package resolution configuration file, which '
- 'supplies a mapping of package names\nto paths. This option cannot be '
- 'used with --package-root.',
+ 'supplies a mapping of package names\nto paths.',
hide: ddc);
parser.addOption(sdkSummaryPathOption,
help: 'The path to the Dart SDK summary file.', hide: hide);
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 7aec79d..711a930 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -28,7 +28,6 @@
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/uri.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/bazel.dart';
import 'package:analyzer/src/workspace/gn.dart';
@@ -36,7 +35,6 @@
import 'package:analyzer/src/workspace/pub.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:args/args.dart';
-import 'package:path/src/context.dart';
import 'package:yaml/yaml.dart';
/// A utility class used to build an analysis context for a given directory.
@@ -183,17 +181,14 @@
// }
Packages createPackageMap(String rootDirectoryPath) {
- String filePath = builderOptions.defaultPackageFilePath;
- if (filePath != null) {
- File configFile = resourceProvider.getFile(filePath);
+ var configPath = builderOptions.defaultPackageFilePath;
+ if (configPath != null) {
+ var configFile = resourceProvider.getFile(configPath);
return parsePackagesFile(resourceProvider, configFile);
+ } else {
+ var resource = resourceProvider.getResource(rootDirectoryPath);
+ return findPackagesFrom(resourceProvider, resource);
}
- String directoryPath = builderOptions.defaultPackagesDirectoryPath;
- if (directoryPath != null) {
- Folder folder = resourceProvider.getFolder(directoryPath);
- return getPackagesFromFolder(folder);
- }
- return findPackagesFromFile(rootDirectoryPath);
}
SourceFactory createSourceFactory(String rootPath, AnalysisOptions options,
@@ -217,28 +212,6 @@
}
}
- /// Finds a package resolution strategy for the directory at the given absolute
- /// [path].
- ///
- /// This function first tries to locate a `.packages` file in the directory. If
- /// that is not found, it instead checks for the presence of a `packages/`
- /// directory in the same place. If that also fails, it starts checking parent
- /// directories for a `.packages` file, and stops if it finds it. Otherwise it
- /// gives up and returns [Packages.empty].
- Packages findPackagesFromFile(String path) {
- Resource location = _findPackagesLocation(path);
- if (location is File) {
- try {
- return parsePackagesFile(resourceProvider, location);
- } catch (_) {
- return Packages.empty;
- }
- } else if (location is Folder) {
- return getPackagesFromFolder(location);
- }
- return Packages.empty;
- }
-
/// Return the SDK that should be used to analyze code. Use the given
/// [workspace] and [analysisOptions] to locate the SDK.
///
@@ -385,96 +358,6 @@
return null;
}
- /// Create a [Packages] object for a 'package' directory ([folder]).
- ///
- /// Package names are resolved as relative to sub-directories of the package
- /// directory.
- ///
- /// TODO(scheglov) Remove this feature
- Packages getPackagesFromFolder(Folder folder) {
- Context pathContext = resourceProvider.pathContext;
- var map = <String, Package>{};
- for (Resource child in folder.getChildren()) {
- if (child is Folder) {
- // Inline resolveSymbolicLinks for performance reasons.
- String packageName = pathContext.basename(child.path);
- String packagePath = resolveSymbolicLink(child);
- var rootFolder = resourceProvider.getFolder(packagePath);
- var libFolder = rootFolder.getChildAssumingFolder('lib');
- var package = Package(
- name: packageName,
- rootFolder: rootFolder,
- libFolder: libFolder,
- languageVersion: null,
- );
- map[packageName] = package;
- }
- }
- return Packages(map);
- }
-
- /// Resolve any symbolic links encoded in the path to the given [folder].
- String resolveSymbolicLink(Folder folder) {
- try {
- return folder.resolveSymbolicLinksSync().path;
- } on FileSystemException {
- return folder.path;
- }
- }
-
- /// Resolve any symbolic links encoded in the URI's in the given [map] by
- /// replacing the values in the map.
- void resolveSymbolicLinks(Map<String, Uri> map) {
- Context pathContext = resourceProvider.pathContext;
- for (String packageName in map.keys) {
- var uri = map[packageName];
- String path = fileUriToNormalizedPath(pathContext, uri);
- Folder folder = resourceProvider.getFolder(path);
- String folderPath = resolveSymbolicLink(folder);
- // Add a '.' so that the URI is suitable for resolving relative URI's
- // against it.
- String uriPath = pathContext.join(folderPath, '.');
- map[packageName] = pathContext.toUri(uriPath);
- }
- }
-
- /// Find the location of the package resolution file/directory for the
- /// directory at the given absolute [path].
- ///
- /// Checks for a `.packages` file in the [path]. If not found,
- /// checks for a `packages` directory in the same directory. If still not
- /// found, starts checking parent directories for `.packages` until reaching
- /// the root directory.
- ///
- /// Return a [File] object representing a `.packages` file if one is found, a
- /// [Folder] object for the `packages/` directory if that is found, or `null`
- /// if neither is found.
- Resource _findPackagesLocation(String path) {
- var resource = resourceProvider.getResource(path);
- while (resource != null) {
- if (resource is Folder) {
- var packageConfigFile = resource
- .getChildAssumingFolder('.dart_tool')
- .getChildAssumingFile('package_config.json');
- if (packageConfigFile.exists) {
- return packageConfigFile;
- }
-
- var dotPackagesFile = resource.getChildAssumingFile('.packages');
- if (dotPackagesFile.exists) {
- return dotPackagesFile;
- }
-
- var packagesDirectory = resource.getChildAssumingFolder('packages');
- if (packagesDirectory.exists) {
- return packagesDirectory;
- }
- }
- resource = resource.parent;
- }
- return null;
- }
-
/// Return the `pubspec.yaml` file that should be used when analyzing code in
/// the directory with the given [path], possibly `null`.
File _findPubspecFile(String path) {
@@ -563,11 +446,6 @@
/// or `null` if the normal lookup mechanism should be used.
String defaultPackageFilePath;
- /// The file path of the packages directory that should be used in place of any
- /// file found using the normal (Package Specification DEP) lookup mechanism,
- /// or `null` if the normal lookup mechanism should be used.
- String defaultPackagesDirectoryPath;
-
/// A list of the paths of summary files that are to be used, or `null` if no
/// summary information is available.
List<String> librarySummaryPaths;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 6f57735..23ba36c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -233,6 +233,8 @@
AnalysisDriverTestView _testView;
+ FeatureSetProvider featureSetProvider;
+
FileSystemState _fsState;
/// The [FileTracker] used by this driver.
@@ -1479,7 +1481,7 @@
void _createFileTracker() {
_fillSalt();
- var featureSetProvider = FeatureSetProvider.build(
+ featureSetProvider = FeatureSetProvider.build(
sourceFactory: sourceFactory,
packages: _packages,
packageDefaultFeatureSet: _analysisOptions.contextFeatures,
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 037c789..816685d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -42,7 +42,8 @@
if (argumentList is ArgumentList) {
var invocation = argumentList.parent;
if (invocation is InstanceCreationExpression) {
- return namedParameterElement(invocation.staticElement);
+ var executable = invocation.constructorName.staticElement;
+ return namedParameterElement(executable);
} else if (invocation is MethodInvocation) {
var executable = invocation.methodName.staticElement;
if (executable is ExecutableElement) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 798129c..86fdc7f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -166,15 +166,18 @@
var existingSource = existingElement?.source;
var libraryRefs = elementFactory.rootReference.children;
var libraryUriList = libraryRefs.map((e) => e.name).toList();
- throw StateError(
- '[The library is already loaded]'
- '[oldUri: ${existingSource.uri}]'
- '[oldPath: ${existingSource.fullName}]'
- '[newUri: ${libraryFile.uriStr}]'
- '[newPath: ${libraryFile.path}]'
- '[cycle: $cycle]'
- '[loadedBundles: ${loadedBundles.toList()}]'
- '[elementFactory.libraries: $libraryUriList]',
+ var statusText = '[The library is already loaded]'
+ '[oldUri: ${existingSource.uri}]'
+ '[oldPath: ${existingSource.fullName}]'
+ '[newUri: ${libraryFile.uriStr}]'
+ '[newPath: ${libraryFile.path}]'
+ '[cycle: $cycle]'
+ '[loadedBundles: ${loadedBundles.toList()}]'
+ '[elementFactory.libraries: $libraryUriList]';
+ throw LibraryCycleLinkException(
+ 'Cycle loading state error',
+ StackTrace.current,
+ {'status': statusText},
);
}
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 8bac535..67b1448 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -806,9 +806,7 @@
}
}
} else {
- if (_propertyMap == null) {
- _propertyMap = HashMap<String, Object>();
- }
+ _propertyMap ??= HashMap<String, Object>();
_propertyMap[name] = value;
}
}
@@ -6022,12 +6020,6 @@
/// The list of arguments to the constructor.
ArgumentListImpl _argumentList;
- /// The element associated with the constructor based on static type
- /// information, or `null` if the AST structure has not been resolved or if
- /// the constructor could not be resolved.
- @override
- ConstructorElement staticElement;
-
/// Initialize a newly created instance creation expression.
InstanceCreationExpressionImpl(this.keyword,
ConstructorNameImpl constructorName, ArgumentListImpl argumentList,
@@ -6081,6 +6073,14 @@
@override
Precedence get precedence => Precedence.primary;
+ @Deprecated('Use constructorName.staticElement')
+ @override
+ ConstructorElement get staticElement => constructorName.staticElement;
+
+ @Deprecated('Use constructorName.staticElement')
+ @override
+ set staticElement(ConstructorElement staticElement) {}
+
/// Return the type arguments associated with the constructor, rather than
/// with the class in which the constructor is defined. It is always an error
/// if there are type arguments because Dart doesn't currently support generic
diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
index 432f8f1..4d7d81d 100644
--- a/pkg/analyzer/lib/src/dart/ast/element_locator.dart
+++ b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
@@ -108,7 +108,7 @@
@override
Element visitInstanceCreationExpression(InstanceCreationExpression node) {
- return node.staticElement;
+ return node.constructorName.staticElement;
}
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 0da70e2..27b83c1 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1094,9 +1094,7 @@
}
token = nonComment(token);
- if (_lastCloned == null) {
- _lastCloned = Token.eof(-1);
- }
+ _lastCloned ??= Token.eof(-1);
while (token != null) {
Token clone = token.copy();
{
@@ -4855,7 +4853,6 @@
_isEqualTokens(node.keyword, toNode.keyword),
_isEqualNodes(node.constructorName, toNode.constructorName),
_isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.staticElement = node.staticElement;
toNode.staticType = node.staticType;
return true;
}
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 9a1d3e7..6e670ce 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -132,7 +132,7 @@
// We need to evaluate the constant to see if any errors occur during its
// evaluation.
- ConstructorElement constructor = node.staticElement;
+ ConstructorElement constructor = node.constructorName.staticElement;
if (constructor != null) {
ConstantVisitor constantVisitor =
ConstantVisitor(_evaluationEngine, _errorReporter);
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 721ad3c..569a568 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -468,13 +468,11 @@
namedNodes ??= const {};
namedValues ??= const {};
- if (invocation == null) {
- invocation = ConstructorInvocation(
- constructor,
- argumentValues,
- namedValues,
- );
- }
+ invocation ??= ConstructorInvocation(
+ constructor,
+ argumentValues,
+ namedValues,
+ );
constructor = followConstantRedirectionChain(constructor);
InterfaceType definingClass = constructor.returnType as InterfaceType;
@@ -603,12 +601,10 @@
argumentValue = argumentValues[i];
errorTarget = arguments[i];
}
- if (errorTarget == null) {
- // No argument node that we can direct error messages to, because we
- // are handling an optional parameter that wasn't specified. So just
- // direct error messages to the constructor call.
- errorTarget = node;
- }
+ // No argument node that we can direct error messages to, because we
+ // are handling an optional parameter that wasn't specified. So just
+ // direct error messages to the constructor call.
+ errorTarget ??= node;
if (argumentValue == null && baseParameter is ParameterElementImpl) {
// The parameter is an optional positional parameter for which no value
// was provided, so use the default value.
@@ -740,9 +736,7 @@
ConstructorElement superConstructor =
superclass.lookUpConstructor(superName, constructor.library);
if (superConstructor != null) {
- if (superArguments == null) {
- superArguments = astFactory.nodeList<Expression>(null);
- }
+ superArguments ??= astFactory.nodeList<Expression>(null);
evaluateSuperConstructorCall(node, fieldMap, superConstructor,
superArguments, initializerVisitor, externalErrorReporter);
@@ -1174,7 +1168,7 @@
_error(node, null);
return null;
}
- ConstructorElement constructor = node.staticElement;
+ ConstructorElement constructor = node.constructorName.staticElement;
if (constructor == null) {
// Couldn't resolve the constructor so we can't compute a value. No
// problem - the error has already been reported.
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 4ed65ae..72e220c 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -55,7 +55,6 @@
expression.keyword = KeywordToken(Keyword.NEW, node.offset);
}
}
- expression.staticElement = node.staticElement;
return expression;
}
@@ -296,7 +295,8 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (node.isConst) {
- ConstructorElement constructor = node.staticElement?.declaration;
+ ConstructorElement constructor =
+ node.constructorName.staticElement?.declaration;
if (constructor != null) {
_callback(constructor);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index aba8c07..0f26e2f 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2735,10 +2735,7 @@
int get hashCode {
// TODO: We might want to re-visit this optimization in the future.
// We cache the hash code value as this is a very frequently called method.
- if (_cachedHashCode == null) {
- _cachedHashCode = location.hashCode;
- }
- return _cachedHashCode;
+ return _cachedHashCode ??= location.hashCode;
}
@override
@@ -3060,9 +3057,7 @@
@override
String getExtendedDisplayName(String shortName) {
- if (shortName == null) {
- shortName = displayName;
- }
+ shortName ??= displayName;
Source source = this.source;
if (source != null) {
return "$shortName (${source.fullName})";
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index 4834c4a..c99951f 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -2,12 +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 'dart:collection';
import 'dart:math' as math;
import 'package:analyzer/dart/ast/ast.dart' show AstNode, ConstructorName;
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/listener.dart' show ErrorReporter;
@@ -15,46 +13,12 @@
import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_constraint_gatherer.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/error/codes.dart' show HintCode, StrongModeCode;
import 'package:analyzer/src/generated/type_system.dart';
import 'package:meta/meta.dart';
-bool _isBottom(DartType t) {
- return (t.isBottom && t.nullabilitySuffix != NullabilitySuffix.question) ||
- identical(t, UnknownInferredType.instance);
-}
-
-/// Is [t] the bottom of the legacy type hierarchy.
-bool _isLegacyBottom(DartType t, {@required bool orTrueBottom}) {
- return (t.isBottom && t.nullabilitySuffix == NullabilitySuffix.question) ||
- t.isDartCoreNull ||
- (orTrueBottom ? _isBottom(t) : false);
-}
-
-/// Is [t] the top of the legacy type hierarch.
-bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
- if (t.isDartAsyncFutureOr) {
- return _isLegacyTop((t as InterfaceType).typeArguments[0],
- orTrueTop: orTrueTop);
- }
- if (t.isDartCoreObject && t.nullabilitySuffix == NullabilitySuffix.none) {
- return true;
- }
- return orTrueTop ? _isTop(t) : false;
-}
-
-bool _isTop(DartType t) {
- if (t.isDartAsyncFutureOr) {
- return _isTop((t as InterfaceType).typeArguments[0]);
- }
- return t.isDynamic ||
- (t.isDartCoreObject && t.nullabilitySuffix != NullabilitySuffix.none) ||
- t.isVoid ||
- identical(t, UnknownInferredType.instance);
-}
-
/// Tracks upper and lower type bounds for a set of type parameters.
///
/// This class is used by calling [isSubtypeOf]. When it encounters one of
@@ -80,19 +44,16 @@
/// infer a single call and discarded immediately afterwards.
class GenericInferrer {
final TypeSystemImpl _typeSystem;
- final Map<TypeParameterElement, List<_TypeConstraint>> constraints = {};
-
- /// Buffer recording constraints recorded while performing a recursive call to
- /// [_matchSubtypeOf] that might fail, so that any constraints recorded during
- /// the failed match can be rewound.
- final _undoBuffer = <_TypeConstraint>[];
+ final Set<TypeParameterElement> _typeParameters = Set.identity();
+ final Map<TypeParameterElement, List<_TypeConstraint>> _constraints = {};
GenericInferrer(
this._typeSystem,
Iterable<TypeParameterElement> typeFormals,
) {
+ _typeParameters.addAll(typeFormals);
for (var formal in typeFormals) {
- constraints[formal] = [];
+ _constraints[formal] = [];
}
}
@@ -185,9 +146,9 @@
inferredTypes[i] = downwardsInferPhase
? _inferTypeParameterFromContext(
- constraints[typeParam], extendsClause,
+ _constraints[typeParam], extendsClause,
isContravariant: typeParam.variance.isContravariant)
- : _inferTypeParameterFromAll(constraints[typeParam], extendsClause,
+ : _inferTypeParameterFromAll(_constraints[typeParam], extendsClause,
isContravariant: typeParam.variance.isContravariant,
preferUpwardsInference: !typeParam.isLegacyCovariant);
}
@@ -202,7 +163,7 @@
var knownTypes = <TypeParameterElement, DartType>{};
for (int i = 0; i < typeFormals.length; i++) {
TypeParameterElement typeParam = typeFormals[i];
- var constraints = this.constraints[typeParam];
+ var constraints = this._constraints[typeParam];
var typeParamBound = typeParam.bound != null
? Substitution.fromPairs(typeFormals, inferredTypes)
.substituteType(typeParam.bound)
@@ -306,11 +267,27 @@
/// attempt have been rewound (see [_rewindConstraints]).
bool tryMatchSubtypeOf(DartType t1, DartType t2, _TypeConstraintOrigin origin,
{@required bool covariant}) {
- int previousRewindBufferLength = _undoBuffer.length;
- bool success = _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
- if (!success) {
- _rewindConstraints(previousRewindBufferLength);
+ var gatherer = TypeConstraintGatherer(
+ typeSystem: _typeSystem,
+ typeParameters: _typeParameters,
+ );
+ var success = gatherer.trySubtypeMatch(t1, t2, !covariant);
+ if (success) {
+ var constraints = gatherer.computeConstraints();
+ for (var entry in constraints.entries) {
+ if (!entry.value.isEmpty) {
+ _constraints[entry.key].add(
+ _TypeConstraint(
+ origin,
+ entry.key,
+ lower: entry.value.lower,
+ upper: entry.value.upper,
+ ),
+ );
+ }
+ }
}
+
return success;
}
@@ -484,265 +461,6 @@
return t;
}
- /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
- ///
- /// The return value indicates whether the match was successful. If it was
- /// unsuccessful, the caller is responsible for ignoring any constraints that
- /// were accumulated (see [_rewindConstraints]).
- bool _matchInterfaceSubtypeOf(InterfaceType i1, InterfaceType i2,
- Set<Element> visited, _TypeConstraintOrigin origin,
- {@required bool covariant}) {
- if (identical(i1, i2)) {
- return true;
- }
-
- if (i1.element == i2.element) {
- return _matchInterfaceSubtypeOf2(i1, i2, origin, covariant);
- }
-
- for (var interface in i1.element.allSupertypes) {
- if (interface.element == i2.element) {
- var substitution = Substitution.fromInterfaceType(i1);
- var substitutedInterface = substitution.substituteType(interface);
- return _matchInterfaceSubtypeOf2(
- substitutedInterface, i2, origin, covariant);
- }
- }
- return false;
- }
-
- /// Tries to make [i1] a subtype of [i2] and accumulate constraints as needed.
- ///
- /// The return value indicates whether the match was successful. If it was
- /// unsuccessful, the caller is responsible for ignoring any constraints that
- /// were accumulated (see [_rewindConstraints]).
- ///
- /// Interfaces [i1] and [i2] are instantiations of the same class element.
- bool _matchInterfaceSubtypeOf2(InterfaceType i1, InterfaceType i2,
- _TypeConstraintOrigin origin, bool covariant) {
- List<DartType> tArgs1 = i1.typeArguments;
- List<DartType> tArgs2 = i2.typeArguments;
- List<TypeParameterElement> tParams = i1.element.typeParameters;
- assert(tArgs1.length == tArgs2.length);
- assert(tArgs1.length == tParams.length);
- for (int i = 0; i < tArgs1.length; i++) {
- TypeParameterElement typeParameterElement = tParams[i];
-
- // TODO (kallentu) : Clean up TypeParameterElementImpl casting once
- // variance is added to the interface.
- Variance parameterVariance =
- (typeParameterElement as TypeParameterElementImpl).variance;
- if (parameterVariance.isCovariant) {
- if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
- covariant: covariant)) {
- return false;
- }
- } else if (parameterVariance.isContravariant) {
- if (!_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
- covariant: !covariant)) {
- return false;
- }
- } else if (parameterVariance.isInvariant) {
- if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], HashSet<Element>(), origin,
- covariant: covariant) ||
- !_matchSubtypeOf(tArgs2[i], tArgs1[i], HashSet<Element>(), origin,
- covariant: !covariant)) {
- return false;
- }
- } else {
- throw StateError("Type parameter ${tParams[i]} has unknown "
- "variance $parameterVariance for inference.");
- }
- }
- return true;
- }
-
- /// Assert that [t1] will be a subtype of [t2], and returns if the constraint
- /// can be satisfied.
- ///
- /// [covariant] must be true if [t1] is a declared type of the generic
- /// function and [t2] is the context type, or false if the reverse. For
- /// example [covariant] is used when [t1] is the declared return type
- /// and [t2] is the context type. Contravariant would be used if [t1] is the
- /// argument type (i.e. passed in to the generic function) and [t2] is the
- /// declared parameter type.
- ///
- /// [origin] indicates where the constraint came from, for example an argument
- /// or return type.
- bool _matchSubtypeOf(DartType t1, DartType t2, Set<Element> visited,
- _TypeConstraintOrigin origin,
- {@required bool covariant}) {
- if (covariant && t1 is TypeParameterType) {
- var constraints = this.constraints[t1.element];
- if (constraints != null) {
- if (!identical(t2, UnknownInferredType.instance)) {
- if (t1.nullabilitySuffix == NullabilitySuffix.question &&
- t2.nullabilitySuffix == NullabilitySuffix.question) {
- t1 = _typeSystem.promoteToNonNull(t1);
- t2 = _typeSystem.promoteToNonNull(t2);
- }
- var constraint = _TypeConstraint(origin, t1.element, upper: t2);
- constraints.add(constraint);
- _undoBuffer.add(constraint);
- }
- return true;
- }
- }
- if (!covariant && t2 is TypeParameterType) {
- var constraints = this.constraints[t2.element];
- if (constraints != null) {
- if (!identical(t1, UnknownInferredType.instance)) {
- if (t1.nullabilitySuffix == NullabilitySuffix.question &&
- t2.nullabilitySuffix == NullabilitySuffix.question) {
- t1 = _typeSystem.promoteToNonNull(t1);
- t2 = _typeSystem.promoteToNonNull(t2);
- }
- var constraint = _TypeConstraint(origin, t2.element, lower: t1);
- constraints.add(constraint);
- _undoBuffer.add(constraint);
- }
- return true;
- }
- }
-
- if (identical(t1, t2)) {
- return true;
- }
-
- // TODO(jmesserly): this logic is taken from subtype.
- bool matchSubtype(DartType t1, DartType t2) {
- return _matchSubtypeOf(t1, t2, null, origin, covariant: covariant);
- }
-
- // Handle FutureOr<T> union type.
- if (t1 is InterfaceType && t1.isDartAsyncFutureOr) {
- var t1TypeArg = t1.typeArguments[0];
- if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
- var t2TypeArg = t2.typeArguments[0];
- // FutureOr<A> <: FutureOr<B> iff A <: B
- return matchSubtype(t1TypeArg, t2TypeArg);
- }
-
- // given t1 is Future<A> | A, then:
- // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
- var t1Future = typeProvider.futureType2(t1TypeArg);
- return matchSubtype(t1Future, t2) && matchSubtype(t1TypeArg, t2);
- }
-
- if (t2 is InterfaceType && t2.isDartAsyncFutureOr) {
- // given t2 is Future<A> | A, then:
- // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
- var t2TypeArg = t2.typeArguments[0];
- var t2Future = typeProvider.futureType2(t2TypeArg);
-
- // First we try matching `t1 <: Future<A>`. If that succeeds *and*
- // records at least one constraint, then we proceed using that constraint.
- var previousRewindBufferLength = _undoBuffer.length;
- var success =
- tryMatchSubtypeOf(t1, t2Future, origin, covariant: covariant);
-
- if (_undoBuffer.length != previousRewindBufferLength) {
- // Trying to match `t1 <: Future<A>` succeeded and recorded constraints,
- // so those are the constraints we want.
- return true;
- } else {
- // Either `t1 <: Future<A>` failed to match, or it matched trivially
- // without recording any constraints (e.g. because t1 is `Null`). We
- // want constraints, because they let us do more precise inference, so
- // go ahead and try matching `t1 <: A` to see if it records any
- // constraints.
- if (tryMatchSubtypeOf(t1, t2TypeArg, origin, covariant: covariant)) {
- // Trying to match `t1 <: A` succeeded. If it recorded constraints,
- // those are the constraints we want. If it didn't, then there's no
- // way we're going to get any constraints. So either way, we want to
- // return `true` since the match suceeded and the constraints we want
- // (if any) have been recorded.
- return true;
- } else {
- // Trying to match `t1 <: A` failed. So there's no way we are going
- // to get any constraints. Just return `success` to indicate whether
- // the match succeeded.
- return success;
- }
- }
- }
-
- // S <: T where S is a type variable
- // T is not dynamic or object (handled above)
- // True if T == S
- // Or true if bound of S is S' and S' <: T
-
- if (t1 is TypeParameterType) {
- // Guard against recursive type parameters
- //
- // TODO(jmesserly): this function isn't guarding against anything (it's
- // not passsing down `visitedSet`, so adding the element has no effect).
- bool guardedSubtype(DartType t1, DartType t2) {
- var visitedSet = visited ?? HashSet<Element>();
- if (visitedSet.add(t1.element)) {
- bool matched = matchSubtype(t1, t2);
- visitedSet.remove(t1.element);
- return matched;
- } else {
- // In the case of a recursive type parameter, consider the subtype
- // match to have failed.
- return false;
- }
- }
-
- if (t2 is TypeParameterType && t1.definition == t2.definition) {
- return guardedSubtype(t1.bound, t2.bound);
- }
- return guardedSubtype(t1.bound, t2);
- }
- if (t2 is TypeParameterType) {
- return false;
- }
-
- // TODO(mfairhurst): switch legacy Bottom checks to true Bottom checks
- // TODO(mfairhurst): switch legacy Top checks to true Top checks
- if (_isLegacyBottom(t1, orTrueBottom: true) ||
- _isLegacyTop(t2, orTrueTop: true)) return true;
-
- if (t1 is InterfaceType && t2 is InterfaceType) {
- return _matchInterfaceSubtypeOf(t1, t2, visited, origin,
- covariant: covariant);
- }
-
- if (t1 is FunctionType && t2 is FunctionType) {
- return FunctionTypeImpl.relate(t1, t2, matchSubtype,
- parameterRelation: (p1, p2) {
- return _matchSubtypeOf(p2.type, p1.type, null, origin,
- covariant: !covariant);
- },
- // Type parameter bounds are invariant.
- boundsRelation: (t1, t2, p1, p2) =>
- matchSubtype(t1, t2) && matchSubtype(t2, t1));
- }
-
- if (t1 is FunctionType && t2 == typeProvider.functionType) {
- return true;
- }
-
- return false;
- }
-
- /// Un-does constraints that were gathered by a failed match attempt, until
- /// [_undoBuffer] has length [previousRewindBufferLength].
- ///
- /// The intended usage is that the caller should record the length of
- /// [_undoBuffer] before attempting to make a match. Then, if the match
- /// fails, pass the recorded length to this method to erase any constraints
- /// that were recorded during the failed match.
- void _rewindConstraints(int previousRewindBufferLength) {
- while (_undoBuffer.length > previousRewindBufferLength) {
- var constraint = _undoBuffer.removeLast();
- var element = constraint.typeParameter;
- assert(identical(constraints[element].last, constraint));
- constraints[element].removeLast();
- }
- }
-
/// If in a legacy library, return the legacy version of the [type].
/// Otherwise, return the original type.
DartType _toLegacyType(DartType type) {
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
new file mode 100644
index 0000000..f4d6a54
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -0,0 +1,574 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:meta/meta.dart';
+
+/// A constraint on the type [parameter] that we're inferring.
+/// We require that `lower <: parameter <: upper`.
+class TypeConstraint {
+ final TypeParameterElement parameter;
+ final DartType lower;
+ final DartType upper;
+
+ TypeConstraint._(this.parameter, this.lower, this.upper);
+
+ bool get isEmpty {
+ return identical(lower, UnknownInferredType.instance) &&
+ identical(upper, UnknownInferredType.instance);
+ }
+
+ @override
+ String toString() {
+ var lowerStr = lower.getDisplayString(withNullability: true);
+ var upperStr = upper.getDisplayString(withNullability: true);
+ return '$lowerStr <: ${parameter.name} <: $upperStr';
+ }
+}
+
+/// Creates sets of [TypeConstraint]s for type parameters, based on an attempt
+/// to make one type schema a subtype of another.
+class TypeConstraintGatherer {
+ final TypeSystemImpl _typeSystem;
+ final Set<TypeParameterElement> _typeParameters = Set.identity();
+ final List<TypeConstraint> _constraints = [];
+
+ TypeConstraintGatherer({
+ @required TypeSystemImpl typeSystem,
+ @required Iterable<TypeParameterElement> typeParameters,
+ }) : _typeSystem = typeSystem {
+ _typeParameters.addAll(typeParameters);
+ }
+
+ DartType get _defaultTypeParameterBound {
+ if (_typeSystem.isNonNullableByDefault) {
+ return _typeSystem.objectQuestion;
+ } else {
+ return DynamicTypeImpl.instance;
+ }
+ }
+
+ /// Returns the set of type constraints that was gathered.
+ Map<TypeParameterElement, TypeConstraint> computeConstraints() {
+ var result = <TypeParameterElement, TypeConstraint>{};
+ for (var parameter in _typeParameters) {
+ result[parameter] = TypeConstraint._(
+ parameter,
+ UnknownInferredType.instance,
+ UnknownInferredType.instance,
+ );
+ }
+
+ for (var constraint in _constraints) {
+ var parameter = constraint.parameter;
+ var mergedConstraint = result[parameter];
+
+ var lower = _typeSystem.getLeastUpperBound(
+ mergedConstraint.lower,
+ constraint.lower,
+ );
+
+ var upper = _typeSystem.getGreatestLowerBound(
+ mergedConstraint.upper,
+ constraint.upper,
+ );
+
+ result[parameter] = TypeConstraint._(parameter, lower, upper);
+ }
+
+ return result;
+ }
+
+ /// Tries to match [P] as a subtype for [Q].
+ ///
+ /// If the match succeeds, the resulting type constraints are recorded for
+ /// later use by [computeConstraints]. If the match fails, the set of type
+ /// constraints is unchanged.
+ bool trySubtypeMatch(DartType P, DartType Q, bool leftSchema) {
+ // If `P` is `_` then the match holds with no constraints.
+ if (identical(P, UnknownInferredType.instance)) {
+ return true;
+ }
+
+ // If `Q` is `_` then the match holds with no constraints.
+ if (identical(Q, UnknownInferredType.instance)) {
+ return true;
+ }
+
+ // If `P` is a type variable `X` in `L`, then the match holds:
+ // Under constraint `_ <: X <: Q`.
+ var P_nullability = P.nullabilitySuffix;
+ if (P is TypeParameterType &&
+ P_nullability == NullabilitySuffix.none &&
+ _typeParameters.contains(P.element)) {
+ _addUpper(P.element, Q);
+ return true;
+ }
+
+ // If `Q` is a type variable `X` in `L`, then the match holds:
+ // Under constraint `P <: X <: _`.
+ var Q_nullability = Q.nullabilitySuffix;
+ if (Q is TypeParameterType &&
+ Q_nullability == NullabilitySuffix.none &&
+ _typeParameters.contains(Q.element)) {
+ _addLower(Q.element, P);
+ return true;
+ }
+
+ // If `P` and `Q` are identical types, then the subtype match holds
+ // under no constraints.
+ if (P == Q) {
+ return true;
+ }
+
+ // If `P` is a legacy type `P0*` then the match holds under constraint
+ // set `C`:
+ // Only if `P0` is a subtype match for `Q` under constraint set `C`.
+ if (P_nullability == NullabilitySuffix.star) {
+ var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
+ return trySubtypeMatch(P0, Q, leftSchema);
+ }
+
+ // If `Q` is a legacy type `Q0*` then the match holds under constraint
+ // set `C`:
+ // Only if `P` is a subtype match for `Q?` under constraint set `C`.
+ if (Q_nullability == NullabilitySuffix.star) {
+ var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
+ return trySubtypeMatch(P, Qq, leftSchema);
+ }
+
+ // If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
+ if (Q_nullability == NullabilitySuffix.none &&
+ Q is InterfaceType &&
+ Q.isDartAsyncFutureOr) {
+ var Q0 = Q.typeArguments[0];
+ var rewind = _constraints.length;
+
+ // If `P` is `FutureOr<P0>` and `P0` is a subtype match for `Q0` under
+ // constraint set `C`.
+ if (P_nullability == NullabilitySuffix.none &&
+ P is InterfaceType &&
+ P.isDartAsyncFutureOr) {
+ var P0 = P.typeArguments[0];
+ if (trySubtypeMatch(P0, Q0, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+ }
+
+ // Or if `P` is a subtype match for `Future<Q0>` under non-empty
+ // constraint set `C`.
+ var futureQ0 = _futureNone(Q0);
+ var P_matches_FutureQ0 = trySubtypeMatch(P, futureQ0, leftSchema);
+ if (P_matches_FutureQ0 && _constraints.length != rewind) {
+ return true;
+ }
+ _constraints.length = rewind;
+
+ // Or if `P` is a subtype match for `Q0` under constraint set `C`.
+ if (trySubtypeMatch(P, Q0, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+
+ // Or if `P` is a subtype match for `Future<Q0>` under empty
+ // constraint set `C`.
+ if (P_matches_FutureQ0) {
+ return true;
+ }
+ }
+
+ // If `Q` is `Q0?` the match holds under constraint set `C`:
+ if (Q_nullability == NullabilitySuffix.question) {
+ var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
+ var rewind = _constraints.length;
+
+ // If `P` is `P0?` and `P0` is a subtype match for `Q0` under
+ // constraint set `C`.
+ if (P_nullability == NullabilitySuffix.question) {
+ var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
+ if (trySubtypeMatch(P0, Q0, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+ }
+
+ // Or if `P` is a subtype match for `Q0` under non-empty
+ // constraint set `C`.
+ var P_matches_Q0 = trySubtypeMatch(P, Q0, leftSchema);
+ if (P_matches_Q0 && _constraints.length != rewind) {
+ return true;
+ }
+ _constraints.length = rewind;
+
+ // Or if `P` is a subtype match for `Null` under constraint set `C`.
+ if (trySubtypeMatch(P, _typeSystem.nullNone, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+
+ // Or if `P` is a subtype match for `Q0` under empty
+ // constraint set `C`.
+ if (P_matches_Q0) {
+ return true;
+ }
+ }
+
+ // If `P` is `FutureOr<P0>` the match holds under constraint set `C1 + C2`:
+ if (P_nullability == NullabilitySuffix.none &&
+ P is InterfaceType &&
+ P.isDartAsyncFutureOr) {
+ var P0 = P.typeArguments[0];
+ var rewind = _constraints.length;
+
+ // If `Future<P0>` is a subtype match for `Q` under constraint set `C1`.
+ // And if `P0` is a subtype match for `Q` under constraint set `C2`.
+ var future_P0 = _futureNone(P0);
+ if (trySubtypeMatch(future_P0, Q, leftSchema) &&
+ trySubtypeMatch(P0, Q, leftSchema)) {
+ return true;
+ }
+
+ _constraints.length = rewind;
+ }
+
+ // If `P` is `P0?` the match holds under constraint set `C1 + C2`:
+ if (P_nullability == NullabilitySuffix.question) {
+ var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
+ var rewind = _constraints.length;
+
+ // If `P0` is a subtype match for `Q` under constraint set `C1`.
+ // And if `Null` is a subtype match for `Q` under constraint set `C2`.
+ if (trySubtypeMatch(P0, Q, leftSchema) &&
+ trySubtypeMatch(_typeSystem.nullNone, Q, leftSchema)) {
+ return true;
+ }
+
+ _constraints.length = rewind;
+ }
+
+ // If `Q` is `dynamic`, `Object?`, or `void` then the match holds under
+ // no constraints.
+ if (identical(Q, DynamicTypeImpl.instance) ||
+ identical(Q, VoidTypeImpl.instance) ||
+ Q_nullability == NullabilitySuffix.question && Q.isDartCoreObject) {
+ return true;
+ }
+
+ // If `P` is `Never` then the match holds under no constraints.
+ if (identical(P, NeverTypeImpl.instance)) {
+ return true;
+ }
+
+ // If `Q` is `Object`, then the match holds under no constraints:
+ // Only if `P` is non-nullable.
+ if (Q_nullability == NullabilitySuffix.none && Q.isDartCoreObject) {
+ return _typeSystem.isNonNullable(P);
+ }
+
+ // If `P` is `Null`, then the match holds under no constraints:
+ // Only if `Q` is nullable.
+ if (P_nullability == NullabilitySuffix.none && P.isDartCoreNull) {
+ return _typeSystem.isNullable(Q);
+ }
+
+ // If `P` is a type variable `X` with bound `B` (or a promoted type
+ // variable `X & B`), the match holds with constraint set `C`:
+ // If `B` is a subtype match for `Q` with constraint set `C`.
+ // Note: we have already eliminated the case that `X` is a variable in `L`.
+ if (P_nullability == NullabilitySuffix.none && P is TypeParameterTypeImpl) {
+ var rewind = _constraints.length;
+ var B = P.promotedBound ?? P.element.bound;
+ if (B != null && trySubtypeMatch(B, Q, leftSchema)) {
+ return true;
+ }
+ _constraints.length = rewind;
+ }
+
+ if (P is InterfaceType && Q is InterfaceType) {
+ return _interfaceType(P, Q, leftSchema);
+ }
+
+ // If `Q` is `Function` then the match holds under no constraints:
+ // If `P` is a function type.
+ if (Q_nullability == NullabilitySuffix.none && Q.isDartCoreFunction) {
+ if (P is FunctionType) {
+ return true;
+ }
+ }
+
+ if (P is FunctionType && Q is FunctionType) {
+ return _functionType(P, Q, leftSchema);
+ }
+
+ return false;
+ }
+
+ void _addLower(TypeParameterElement element, DartType lower) {
+ _constraints.add(
+ TypeConstraint._(element, lower, UnknownInferredType.instance),
+ );
+ }
+
+ void _addUpper(TypeParameterElement element, DartType upper) {
+ _constraints.add(
+ TypeConstraint._(element, UnknownInferredType.instance, upper),
+ );
+ }
+
+ bool _functionType(FunctionType P, FunctionType Q, bool leftSchema) {
+ if (P.nullabilitySuffix != NullabilitySuffix.none) {
+ return false;
+ }
+
+ if (Q.nullabilitySuffix != NullabilitySuffix.none) {
+ return false;
+ }
+
+ var P_typeFormals = P.typeFormals;
+ var Q_typeFormals = Q.typeFormals;
+ if (P_typeFormals.length != Q_typeFormals.length) {
+ return false;
+ }
+
+ if (P_typeFormals.isEmpty && Q_typeFormals.isEmpty) {
+ return _functionType0(P, Q, leftSchema);
+ }
+
+ // We match two generic function types:
+ // `<T0 extends B00, ..., Tn extends B0n>F0`
+ // `<S0 extends B10, ..., Sn extends B1n>F1`
+ // with respect to `L` under constraint set `C2`:
+ var rewind = _constraints.length;
+
+ // If `B0i` is a subtype match for `B1i` with constraint set `Ci0`.
+ // If `B1i` is a subtype match for `B0i` with constraint set `Ci1`.
+ // And `Ci2` is `Ci0 + Ci1`.
+ for (var i = 0; i < P_typeFormals.length; i++) {
+ var B0 = P_typeFormals[i].bound ?? _defaultTypeParameterBound;
+ var B1 = Q_typeFormals[i].bound ?? _defaultTypeParameterBound;
+ if (!trySubtypeMatch(B0, B1, leftSchema)) {
+ _constraints.length = rewind;
+ return false;
+ }
+ if (!trySubtypeMatch(B1, B0, !leftSchema)) {
+ _constraints.length = rewind;
+ return false;
+ }
+ }
+
+ // And `Z0...Zn` are fresh variables with bounds `B20, ..., B2n`.
+ // Where `B2i` is `B0i[Z0/T0, ..., Zn/Tn]` if `P` is a type schema.
+ // Or `B2i` is `B1i[Z0/S0, ..., Zn/Sn]` if `Q` is a type schema.
+ // In other words, we choose the bounds for the fresh variables from
+ // whichever of the two generic function types is a type schema and does
+ // not contain any variables from `L`.
+ var newTypeParameters = <TypeParameterElement>[];
+ for (var i = 0; i < P_typeFormals.length; i++) {
+ var Z = TypeParameterElementImpl('Z$i', -1);
+ if (leftSchema) {
+ Z.bound = P_typeFormals[i].bound;
+ } else {
+ Z.bound = Q_typeFormals[i].bound;
+ }
+ newTypeParameters.add(Z);
+ }
+
+ // And `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for
+ // `F1[Z0/S0, ..., Zn/Sn]` with respect to `L` under constraints `C0`.
+ var typeArguments = newTypeParameters
+ .map((e) => e.instantiate(nullabilitySuffix: NullabilitySuffix.none))
+ .toList();
+ var P_instantiated = P.instantiate(typeArguments);
+ var Q_instantiated = Q.instantiate(typeArguments);
+ if (!_functionType0(P_instantiated, Q_instantiated, leftSchema)) {
+ _constraints.length = rewind;
+ return false;
+ }
+
+ // And `C1` is `C02 + ... + Cn2 + C0`.
+ // And `C2` is `C1` with each constraint replaced with its closure
+ // with respect to `[Z0, ..., Zn]`.
+ // TODO(scheglov) do closure
+
+ return true;
+ }
+
+ /// A function type `(M0,..., Mn, [M{n+1}, ..., Mm]) -> R0` is a subtype
+ /// match for a function type `(N0,..., Nk, [N{k+1}, ..., Nr]) -> R1` with
+ /// respect to `L` under constraints `C0 + ... + Cr + C`.
+ bool _functionType0(FunctionType f, FunctionType g, bool leftSchema) {
+ var rewind = _constraints.length;
+
+ // If `R0` is a subtype match for a type `R1` with respect to `L` under
+ // constraints `C`.
+ if (!trySubtypeMatch(f.returnType, g.returnType, leftSchema)) {
+ _constraints.length = rewind;
+ return false;
+ }
+
+ var fParameters = f.parameters;
+ var gParameters = g.parameters;
+
+ // And for `i` in `0...r`, `Ni` is a subtype match for `Mi` with respect
+ // to `L` under constraints `Ci`.
+ var fIndex = 0;
+ var gIndex = 0;
+ while (fIndex < fParameters.length && gIndex < gParameters.length) {
+ var fParameter = fParameters[fIndex];
+ var gParameter = gParameters[gIndex];
+ if (fParameter.isRequiredPositional) {
+ if (gParameter.isRequiredPositional) {
+ if (trySubtypeMatch(gParameter.type, fParameter.type, leftSchema)) {
+ fIndex++;
+ gIndex++;
+ } else {
+ _constraints.length = rewind;
+ return false;
+ }
+ } else {
+ _constraints.length = rewind;
+ return false;
+ }
+ } else if (fParameter.isOptionalPositional) {
+ if (gParameter.isPositional) {
+ if (trySubtypeMatch(gParameter.type, fParameter.type, leftSchema)) {
+ fIndex++;
+ gIndex++;
+ } else {
+ _constraints.length = rewind;
+ return false;
+ }
+ } else {
+ _constraints.length = rewind;
+ return false;
+ }
+ } else if (fParameter.isNamed) {
+ if (gParameter.isNamed) {
+ var compareNames = fParameter.name.compareTo(gParameter.name);
+ if (compareNames == 0) {
+ if (trySubtypeMatch(gParameter.type, fParameter.type, leftSchema)) {
+ fIndex++;
+ gIndex++;
+ } else {
+ _constraints.length = rewind;
+ return false;
+ }
+ } else if (compareNames < 0) {
+ if (fParameter.isRequiredNamed) {
+ _constraints.length = rewind;
+ return false;
+ } else {
+ fIndex++;
+ }
+ } else {
+ assert(compareNames > 0);
+ // The subtype must accept all parameters of the supertype.
+ _constraints.length = rewind;
+ return false;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ // The supertype must provide all required parameters to the subtype.
+ while (fIndex < fParameters.length) {
+ var fParameter = fParameters[fIndex++];
+ if (fParameter.isNotOptional) {
+ _constraints.length = rewind;
+ return false;
+ }
+ }
+
+ // The subtype must accept all parameters of the supertype.
+ assert(fIndex == fParameters.length);
+ if (gIndex < gParameters.length) {
+ _constraints.length = rewind;
+ return false;
+ }
+
+ return true;
+ }
+
+ InterfaceType _futureNone(DartType argument) {
+ var element = _typeSystem.typeProvider.futureElement;
+ return element.instantiate(
+ typeArguments: [argument],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
+
+ bool _interfaceType(InterfaceType P, InterfaceType Q, bool leftSchema) {
+ if (P.nullabilitySuffix != NullabilitySuffix.none) {
+ return false;
+ }
+
+ if (Q.nullabilitySuffix != NullabilitySuffix.none) {
+ return false;
+ }
+
+ // If `P` is `C<M0, ..., Mk> and `Q` is `C<N0, ..., Nk>`, then the match
+ // holds under constraints `C0 + ... + Ck`:
+ // If `Mi` is a subtype match for `Ni` with respect to L under
+ // constraints `Ci`.
+ if (P.element == Q.element) {
+ if (!_interfaceType_arguments(P, Q, leftSchema)) {
+ return false;
+ }
+ return true;
+ }
+
+ // If `P` is `C0<M0, ..., Mk>` and `Q` is `C1<N0, ..., Nj>` then the match
+ // holds with respect to `L` under constraints `C`:
+ // If `C1<B0, ..., Bj>` is a superinterface of `C0<M0, ..., Mk>` and
+ // `C1<B0, ..., Bj>` is a subtype match for `C1<N0, ..., Nj>` with
+ // respect to `L` under constraints `C`.
+ var C0 = P.element;
+ var C1 = Q.element;
+ for (var interface in C0.allSupertypes) {
+ if (interface.element == C1) {
+ var substitution = Substitution.fromInterfaceType(P);
+ return _interfaceType_arguments(
+ substitution.substituteType(interface),
+ Q,
+ leftSchema,
+ );
+ }
+ }
+
+ return false;
+ }
+
+ /// Match arguments of [P] against arguments of [Q].
+ /// If returns `false`, the constraints are unchanged.
+ bool _interfaceType_arguments(
+ InterfaceType P,
+ InterfaceType Q,
+ bool leftSchema,
+ ) {
+ assert(P.element == Q.element);
+
+ var rewind = _constraints.length;
+
+ for (var i = 0; i < P.typeArguments.length; i++) {
+ var M = P.typeArguments[i];
+ var N = Q.typeArguments[i];
+ if (!trySubtypeMatch(M, N, leftSchema)) {
+ _constraints.length = rewind;
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 495f5ca..0f67958 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -369,19 +369,16 @@
@deprecated
@override
DartObjectImpl get nullObject {
- if (_nullObject == null) {
- _nullObject = DartObjectImpl(
- TypeSystemImpl(
- implicitCasts: false,
- isNonNullableByDefault: false,
- strictInference: false,
- typeProvider: this,
- ),
- nullType,
- NullState.NULL_STATE,
- );
- }
- return _nullObject;
+ return _nullObject ??= DartObjectImpl(
+ TypeSystemImpl(
+ implicitCasts: false,
+ isNonNullableByDefault: false,
+ strictInference: false,
+ typeProvider: this,
+ ),
+ nullType,
+ NullState.NULL_STATE,
+ );
}
InterfaceTypeImpl get nullStar {
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index a805bcd..710453b8 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -90,9 +90,9 @@
*
* TODO(scheglov) Remove after https://github.com/dart-lang/sdk/issues/31925
*/
- final Set<ConstantEvaluationTarget> _libraryConstants = Set();
+ final Set<ConstantEvaluationTarget> _libraryConstants = {};
- final Set<ConstantEvaluationTarget> _constants = Set();
+ final Set<ConstantEvaluationTarget> _constants = {};
final String Function(String path) getFileContent;
@@ -547,7 +547,7 @@
ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
LibraryIdentifier libraryNameNode;
- var seenPartSources = Set<Source>();
+ var seenPartSources = <Source>{};
var directivesToResolve = <Directive>[];
int partIndex = 0;
for (Directive directive in definingCompilationUnit.directives) {
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 3e80669..7133ec0 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -61,8 +61,8 @@
final List<FileState> importedFiles = [];
final List<FileState> exportedFiles = [];
final List<FileState> partedFiles = [];
- final Set<FileState> directReferencedFiles = Set();
- final Set<FileState> directReferencedLibraries = Set();
+ final Set<FileState> directReferencedFiles = {};
+ final Set<FileState> directReferencedLibraries = {};
final List<FileState> libraryFiles = [];
FileState partOfLibrary;
@@ -545,7 +545,7 @@
final List<FileState> libraries = [];
/// The library cycles that this cycle references directly.
- final Set<LibraryCycle> directDependencies = Set<LibraryCycle>();
+ final Set<LibraryCycle> directDependencies = <LibraryCycle>{};
/// The transitive signature of this cycle.
///
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index 098854c..15f53c7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -107,15 +107,11 @@
*/
void _analyzeLeastUpperBoundTypes(
Expression node, DartType staticType1, DartType staticType2) {
- if (staticType1 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType1 = DynamicTypeImpl.instance;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType1 ??= DynamicTypeImpl.instance;
- if (staticType2 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType2 = DynamicTypeImpl.instance;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType2 ??= DynamicTypeImpl.instance;
DartType staticType =
_typeSystem.getLeastUpperBound(staticType1, staticType2) ??
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index 9bb990e..0c70edc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -84,15 +84,11 @@
/// TODO(scheglov) this is duplicate
void _analyzeLeastUpperBoundTypes(
Expression node, DartType staticType1, DartType staticType2) {
- if (staticType1 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType1 = DynamicTypeImpl.instance;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType1 ??= DynamicTypeImpl.instance;
- if (staticType2 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType2 = DynamicTypeImpl.instance;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType2 ??= DynamicTypeImpl.instance;
DartType staticType =
_typeSystem.getLeastUpperBound(staticType1, staticType2) ??
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 5d517cb..4bc73dc 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -55,6 +55,7 @@
DartType uninstantiatedType, TypeArgumentList typeArguments,
{AstNode errorNode, bool isConst = false}) {
errorNode ??= inferenceNode;
+ uninstantiatedType = _getFreshType(uninstantiatedType);
if (typeArguments == null &&
uninstantiatedType is FunctionType &&
uninstantiatedType.typeFormals.isNotEmpty) {
@@ -295,6 +296,8 @@
@required bool isConst,
@required AstNode errorNode,
}) {
+ rawType = _getFreshType(rawType);
+
// Get the parameters that correspond to the uninstantiated generic.
List<ParameterElement> rawParameters =
ResolverVisitor.resolveArgumentsToParameters(
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 6e73920..07d96a2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -308,12 +308,8 @@
if (propertyName.inSetterContext()) {
element = classElement.getSetter(name);
}
- if (element == null) {
- element = classElement.getGetter(name);
- }
- if (element == null) {
- element = classElement.getMethod(name);
- }
+ element ??= classElement.getGetter(name);
+ element ??= classElement.getMethod(name);
if (element != null && element.isAccessibleIn(_definingLibrary)) {
return element;
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index cbf7366..e6b0ac6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -3,13 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
@@ -69,169 +67,44 @@
void resolveTypeName(TypeName node) {
rewriteResult = null;
- Identifier typeName = node.name;
+ var typeIdentifier = node.name;
- if (typeName is SimpleIdentifier && typeName.name == 'void') {
+ if (typeIdentifier is SimpleIdentifier && typeIdentifier.name == 'void') {
node.type = VoidTypeImpl.instance;
return;
}
- _setElement(typeName, null); // Clear old Elements from previous run.
-
- TypeArgumentList argumentList = node.typeArguments;
- Element element = nameScope.lookup(typeName, definingLibrary);
- if (element == null) {
- node.type = dynamicType;
- if (nameScope.shouldIgnoreUndefined(typeName)) {
- return;
- }
- //
- // If not, the look to see whether we might have created the wrong AST
- // structure for a constructor name. If so, fix the AST structure and then
- // proceed.
- //
- AstNode parent = node.parent;
- if (typeName is PrefixedIdentifier &&
- parent is ConstructorName &&
- argumentList == null) {
- ConstructorName name = parent;
- if (name.name == null) {
- PrefixedIdentifier prefixedIdentifier =
- typeName as PrefixedIdentifier;
- SimpleIdentifier prefix = prefixedIdentifier.prefix;
- element = nameScope.lookup(prefix, definingLibrary);
- if (element is PrefixElement) {
- if (nameScope.shouldIgnoreUndefined(typeName)) {
- return;
- }
- AstNode grandParent = parent.parent;
- if (grandParent is InstanceCreationExpression &&
- grandParent.isConst) {
- // If, if this is a const expression, then generate a
- // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.CONST_WITH_NON_TYPE,
- prefixedIdentifier.identifier,
- [prefixedIdentifier.identifier.name],
- );
- } else {
- // Else, if this expression is a new expression, report a
- // NEW_WITH_NON_TYPE warning.
- errorReporter.reportErrorForNode(
- StaticWarningCode.NEW_WITH_NON_TYPE,
- prefixedIdentifier.identifier,
- [prefixedIdentifier.identifier.name],
- );
- }
- _setElement(prefix, element);
- return;
- } else if (element != null) {
- //
- // Rewrite the constructor name. The parser, when it sees a
- // constructor named "a.b", cannot tell whether "a" is a prefix and
- // "b" is a class name, or whether "a" is a class name and "b" is a
- // constructor name. It arbitrarily chooses the former, but in this
- // case was wrong.
- //
- name.name = prefixedIdentifier.identifier;
- name.period = prefixedIdentifier.period;
- node.name = prefix;
- typeName = prefix;
- rewriteResult = parent;
- }
- }
- }
- if (nameScope.shouldIgnoreUndefined(typeName)) {
- return;
- }
- }
+ var element = nameScope.lookup(typeIdentifier, definingLibrary);
if (element is MultiplyDefinedElement) {
- _setElement(typeName, element);
+ _setElement(typeIdentifier, element);
node.type = dynamicType;
return;
}
- var errorHelper = _ErrorHelper(errorReporter);
- if (errorHelper.checkNewWithNonType(node, element)) {
- _setElement(typeName, element);
- node.type = dynamicType;
+ if (element != null) {
+ _setElement(typeIdentifier, element);
+ node.type = _instantiateElement(node, element);
return;
}
- if (element == null) {
- if (errorHelper.checkNullOrNonTypeElement(node, element)) {
- _setElement(typeName, element);
- node.type = dynamicType;
- return;
- }
-
- if (typeName is PrefixedIdentifier &&
- node.parent is ConstructorName &&
- argumentList != null) {
- SimpleIdentifier prefix = (typeName as PrefixedIdentifier).prefix;
- SimpleIdentifier identifier =
- (typeName as PrefixedIdentifier).identifier;
- Element prefixElement = nameScope.lookup(prefix, definingLibrary);
- ClassElement classElement;
- ConstructorElement constructorElement;
- if (prefixElement is ClassElement) {
- classElement = prefixElement;
- constructorElement =
- prefixElement.getNamedConstructor(identifier.name);
- }
- if (constructorElement != null) {
- errorReporter.reportErrorForNode(
- StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
- argumentList,
- [prefix.name, identifier.name],
- );
- prefix.staticElement = prefixElement;
- identifier.staticElement = constructorElement;
- AstNode grandParent = node.parent.parent;
- if (grandParent is InstanceCreationExpressionImpl) {
- var instanceType = classElement.instantiate(
- typeArguments: List.filled(
- classElement.typeParameters.length,
- dynamicType,
- ),
- nullabilitySuffix: _noneOrStarSuffix,
- );
- grandParent.staticElement = constructorElement;
- grandParent.staticType = instanceType;
- //
- // Re-write the AST to reflect the resolution.
- //
- TypeName newTypeName = astFactory.typeName(prefix, null);
- newTypeName.type = instanceType;
- ConstructorName newConstructorName = astFactory.constructorName(
- newTypeName,
- (typeName as PrefixedIdentifier).period,
- identifier);
- newConstructorName.staticElement = constructorElement;
- NodeReplacer.replace(node.parent, newConstructorName);
- grandParent.typeArguments = node.typeArguments;
- // Re-assign local variables that have effectively changed.
- node = newTypeName;
- typeName = prefix;
- element = prefixElement;
- argumentList = null;
- rewriteResult = newConstructorName;
- }
- } else {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_CLASS,
- typeName,
- [typeName.name],
- );
- }
- } else {
- errorHelper.reportUnresolvedElement(node);
- }
+ if (_rewriteToConstructorName(node)) {
+ return;
}
- _setElement(typeName, element);
- node.type = _instantiateElement(node, element);
+ // Full `prefix.Name` cannot be resolved, try to resolve 'prefix' alone.
+ if (typeIdentifier is PrefixedIdentifier) {
+ var prefixIdentifier = typeIdentifier.prefix;
+ var prefixElement = nameScope.lookup(prefixIdentifier, definingLibrary);
+ prefixIdentifier.staticElement = prefixElement;
+ }
+
+ node.type = dynamicType;
+ if (nameScope.shouldIgnoreUndefined(typeIdentifier)) {
+ return;
+ }
+
+ _ErrorHelper(errorReporter).reportNullOrNonTypeElement(node, null);
}
/// Return type arguments, exactly [parameterCount].
@@ -315,6 +188,9 @@
typeArguments: typeArguments,
nullabilitySuffix: nullability,
);
+ } else if (_isInstanceCreation(node)) {
+ _ErrorHelper(errorReporter).reportNewWithNonType(node);
+ return dynamicType;
} else if (element is DynamicElementImpl) {
_buildTypeArguments(node, 0);
return DynamicTypeImpl.instance;
@@ -340,7 +216,7 @@
nullabilitySuffix: nullability,
);
} else {
- _ErrorHelper(errorReporter).checkNullOrNonTypeElement(node, element);
+ _ErrorHelper(errorReporter).reportNullOrNonTypeElement(node, element);
return dynamicType;
}
}
@@ -362,6 +238,9 @@
classElement: element,
nullabilitySuffix: nullability,
);
+ } else if (_isInstanceCreation(node)) {
+ _ErrorHelper(errorReporter).reportNewWithNonType(node);
+ return dynamicType;
} else if (element is DynamicElementImpl) {
return DynamicTypeImpl.instance;
} else if (element is FunctionTypeAliasElement) {
@@ -378,7 +257,7 @@
nullabilitySuffix: nullability,
);
} else {
- _ErrorHelper(errorReporter).checkNullOrNonTypeElement(node, element);
+ _ErrorHelper(errorReporter).reportNullOrNonTypeElement(node, element);
return dynamicType;
}
}
@@ -410,6 +289,49 @@
}
}
+ /// We parse `foo.bar` as `prefix.Name` with the expectation that `prefix`
+ /// will be a [PrefixElement]. But we checked and found that `foo.bar` is
+ /// not in the scope, so try to see if it is `Class.constructor`.
+ ///
+ /// Return `true` if the node was rewritten as `Class.constructor`.
+ bool _rewriteToConstructorName(TypeName node) {
+ var typeIdentifier = node.name;
+ var constructorName = node.parent;
+ if (typeIdentifier is PrefixedIdentifier &&
+ constructorName is ConstructorName &&
+ constructorName.name == null) {
+ var classIdentifier = typeIdentifier.prefix;
+ var classElement = nameScope.lookup(classIdentifier, definingLibrary);
+ if (classElement is ClassElement) {
+ var constructorIdentifier = typeIdentifier.identifier;
+
+ var typeArguments = node.typeArguments;
+ if (typeArguments != null) {
+ errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+ typeArguments,
+ [classIdentifier.name, constructorIdentifier.name],
+ );
+ var instanceCreation = constructorName.parent;
+ if (instanceCreation is InstanceCreationExpressionImpl) {
+ instanceCreation.typeArguments = typeArguments;
+ }
+ }
+
+ node.name = classIdentifier;
+ node.typeArguments = null;
+
+ constructorName.period = typeIdentifier.period;
+ constructorName.name = constructorIdentifier;
+
+ rewriteResult = constructorName;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/// Records the new Element for a TypeName's Identifier.
///
/// A null may be passed in to indicate that the element can't be resolved.
@@ -424,6 +346,11 @@
prefix.staticElement = nameScope.lookup(prefix, definingLibrary);
}
}
+
+ static bool _isInstanceCreation(TypeName node) {
+ return node.parent is ConstructorName &&
+ node.parent.parent is InstanceCreationExpression;
+ }
}
/// Helper for reporting errors during type name resolution.
@@ -432,148 +359,156 @@
_ErrorHelper(this.errorReporter);
- bool checkNewWithNonType(TypeName node, Element element) {
- if (element != null && element is! ClassElement) {
- var constructorName = node.parent;
- if (constructorName is ConstructorName) {
- var instanceCreation = constructorName.parent;
- if (instanceCreation is InstanceCreationExpression) {
- var identifier = node.name;
- var simpleIdentifier = _getSimpleIdentifier(identifier);
- if (instanceCreation.isConst) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.CONST_WITH_NON_TYPE,
- simpleIdentifier,
- [identifier],
- );
- } else {
- errorReporter.reportErrorForNode(
- StaticWarningCode.NEW_WITH_NON_TYPE,
- simpleIdentifier,
- [identifier],
- );
- }
- return true;
- }
+ bool reportNewWithNonType(TypeName node) {
+ var constructorName = node.parent;
+ if (constructorName is ConstructorName) {
+ var instanceCreation = constructorName.parent;
+ if (instanceCreation is InstanceCreationExpression) {
+ var identifier = node.name;
+ var errorNode = _getErrorNode(node);
+ errorReporter.reportErrorForNode(
+ instanceCreation.isConst
+ ? CompileTimeErrorCode.CONST_WITH_NON_TYPE
+ : StaticWarningCode.NEW_WITH_NON_TYPE,
+ errorNode,
+ [identifier.name],
+ );
+ return true;
}
}
-
return false;
}
- bool checkNullOrNonTypeElement(TypeName node, Element element) {
- var typeName = node.name;
- SimpleIdentifier typeNameSimple = _getSimpleIdentifier(typeName);
- if (typeNameSimple.name == "boolean") {
+ void reportNullOrNonTypeElement(TypeName node, Element element) {
+ var identifier = node.name;
+ var errorNode = _getErrorNode(node);
+
+ if (errorNode.name == 'boolean') {
errorReporter.reportErrorForNode(
StaticWarningCode.UNDEFINED_CLASS_BOOLEAN,
- typeNameSimple,
+ errorNode,
);
- return true;
- } else if (_isTypeInCatchClause(node)) {
+ return;
+ }
+
+ if (_isTypeInCatchClause(node)) {
errorReporter.reportErrorForNode(
StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
- return true;
- } else if (_isTypeInAsExpression(node)) {
+ return;
+ }
+
+ if (_isTypeInAsExpression(node)) {
errorReporter.reportErrorForNode(
StaticWarningCode.CAST_TO_NON_TYPE,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
- return true;
- } else if (_isTypeInIsExpression(node)) {
+ return;
+ }
+
+ if (_isTypeInIsExpression(node)) {
if (element != null) {
errorReporter.reportErrorForNode(
StaticWarningCode.TYPE_TEST_WITH_NON_TYPE,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
} else {
errorReporter.reportErrorForNode(
StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
}
- return true;
- } else if (_isRedirectingConstructor(node)) {
+ return;
+ }
+
+ if (_isRedirectingConstructor(node)) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_TO_NON_CLASS,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
- return true;
- } else if (_isTypeInTypeArgumentList(node)) {
+ return;
+ }
+
+ if (_isTypeInTypeArgumentList(node)) {
errorReporter.reportErrorForNode(
StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
- typeName,
- [typeName.name],
+ identifier,
+ [identifier.name],
);
- return true;
- } else if (element != null) {
- var parent = node.parent;
- if (parent is ExtendsClause ||
- parent is ImplementsClause ||
- parent is WithClause ||
- parent is ClassTypeAlias) {
- // Ignored. The error will be reported elsewhere.
- } else if (element is LocalVariableElement ||
- (element is FunctionElement &&
- element.enclosingElement is ExecutableElement)) {
- errorReporter.reportError(
- DiagnosticFactory().referencedBeforeDeclaration(
- errorReporter.source,
- typeName,
- element: element,
- ),
- );
- } else {
- errorReporter.reportErrorForNode(
- StaticWarningCode.NOT_A_TYPE,
- typeName,
- [typeName.name],
- );
- }
- return true;
+ return;
}
- return false;
- }
- void reportUnresolvedElement(TypeName node) {
- var identifier = node.name;
+ if (reportNewWithNonType(node)) {
+ return;
+ }
+
+ var parent = node.parent;
+ if (parent is ExtendsClause ||
+ parent is ImplementsClause ||
+ parent is WithClause ||
+ parent is ClassTypeAlias) {
+ // Ignored. The error will be reported elsewhere.
+ return;
+ }
+
+ if (element is LocalVariableElement ||
+ (element is FunctionElement &&
+ element.enclosingElement is ExecutableElement)) {
+ errorReporter.reportError(
+ DiagnosticFactory().referencedBeforeDeclaration(
+ errorReporter.source,
+ identifier,
+ element: element,
+ ),
+ );
+ return;
+ }
+
+ if (element != null) {
+ errorReporter.reportErrorForNode(
+ StaticWarningCode.NOT_A_TYPE,
+ identifier,
+ [identifier.name],
+ );
+ return;
+ }
+
if (identifier is SimpleIdentifier && identifier.name == 'await') {
errorReporter.reportErrorForNode(
StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
node,
);
- } else {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_CLASS,
- identifier,
- [identifier.name],
- );
+ return;
}
+
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_CLASS,
+ identifier,
+ [identifier.name],
+ );
}
/// Returns the simple identifier of the given (maybe prefixed) identifier.
- static SimpleIdentifier _getSimpleIdentifier(Identifier identifier) {
- if (identifier is SimpleIdentifier) {
- return identifier;
- } else {
- PrefixedIdentifier prefixed = identifier;
- SimpleIdentifier prefix = prefixed.prefix;
+ static Identifier _getErrorNode(TypeName node) {
+ Identifier identifier = node.name;
+ if (identifier is PrefixedIdentifier) {
// The prefixed identifier can be:
// 1. new importPrefix.TypeName()
// 2. new TypeName.constructorName()
// 3. new unresolved.Unresolved()
- if (prefix.staticElement is PrefixElement) {
- return prefixed.identifier;
+ if (identifier.prefix.staticElement is PrefixElement) {
+ return identifier.identifier;
} else {
- return prefix;
+ return identifier;
}
+ } else {
+ return identifier;
}
}
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index a6938c2..69b3722 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -479,25 +479,19 @@
* Return the directory within the SDK directory that contains the libraries.
*/
Folder get libraryDirectory {
- if (_libraryDirectory == null) {
- _libraryDirectory =
- _sdkDirectory.getChildAssumingFolder(_LIB_DIRECTORY_NAME);
- }
- return _libraryDirectory;
+ return _libraryDirectory ??=
+ _sdkDirectory.getChildAssumingFolder(_LIB_DIRECTORY_NAME);
}
/**
* Return the file containing the Pub executable, or `null` if it does not exist.
*/
File get pubExecutable {
- if (_pubExecutable == null) {
- _pubExecutable = _sdkDirectory
- .getChildAssumingFolder(_BIN_DIRECTORY_NAME)
- .getChildAssumingFile(OSUtilities.isWindows()
- ? _PUB_EXECUTABLE_NAME_WIN
- : _PUB_EXECUTABLE_NAME);
- }
- return _pubExecutable;
+ return _pubExecutable ??= _sdkDirectory
+ .getChildAssumingFolder(_BIN_DIRECTORY_NAME)
+ .getChildAssumingFile(OSUtilities.isWindows()
+ ? _PUB_EXECUTABLE_NAME_WIN
+ : _PUB_EXECUTABLE_NAME);
}
/**
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index e89db2c..4e9ba42 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -287,6 +287,12 @@
}
@override
+ void visitConstructorName(ConstructorName node) {
+ _checkForDeprecatedMemberUse(node.staticElement, node);
+ super.visitConstructorName(node);
+ }
+
+ @override
void visitExportDirective(ExportDirective node) {
_checkForDeprecatedMemberUse(node.uriElement, node);
super.visitExportDirective(node);
@@ -445,7 +451,6 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
- _checkForDeprecatedMemberUse(node.staticElement, node);
_checkForLiteralConstructorUse(node);
super.visitInstanceCreationExpression(node);
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 38fb787..038437f 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1430,7 +1430,8 @@
*/
static const CompileTimeErrorCode CONST_WITH_NON_TYPE = CompileTimeErrorCode(
'CONST_WITH_NON_TYPE', "The name '{0}' isn't a class.",
- correction: "Try correcting the name to match an existing class.");
+ correction: "Try correcting the name to match an existing class.",
+ isUnresolvedIdentifier: true);
/**
* 16.12.2 Const: If <i>T</i> is a parameterized type, it is a compile-time
@@ -2117,7 +2118,8 @@
correction:
"Try specifying a different superclass, or removing the extends "
"clause.",
- hasPublishedDocs: true);
+ hasPublishedDocs: true,
+ isUnresolvedIdentifier: true);
/**
* Parameters:
@@ -9191,7 +9193,8 @@
*/
static const StaticWarningCode NEW_WITH_NON_TYPE = StaticWarningCode(
'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
- correction: "Try correcting the name to match an existing class.");
+ correction: "Try correcting the name to match an existing class.",
+ isUnresolvedIdentifier: true);
/**
* 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
index 79f497e..7f8baf6 100644
--- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart
+++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
@@ -331,9 +331,7 @@
for (SimpleIdentifier name in names) {
String nameStr = name.name;
Element element = namespace.get(nameStr);
- if (element == null) {
- element = namespace.get("$nameStr=");
- }
+ element ??= namespace.get("$nameStr=");
if (element == null) {
_errorReporter
.reportErrorForNode(hintCode, name, [library.identifier, nameStr]);
@@ -582,7 +580,7 @@
final List<CatchClause> catchClauses;
bool _done = false;
- List<DartType> _visitedTypes = <DartType>[];
+ final List<DartType> _visitedTypes = <DartType>[];
_CatchClausesVerifier(
this._typeSystem,
diff --git a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
index 09aa5c6..9c75de7 100644
--- a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
+++ b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
@@ -32,7 +32,7 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
_check(
- node.staticElement?.parameters,
+ node.constructorName.staticElement?.parameters,
node.argumentList,
node.constructorName,
);
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 433b172..2811c3a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -455,7 +455,6 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
ConstructorElement invokedConstructor = node.constructorName.staticElement;
- node.staticElement = invokedConstructor;
ArgumentList argumentList = node.argumentList;
List<ParameterElement> parameters =
_resolveArgumentsToFunction(argumentList, invokedConstructor);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 785ccbd..8145c6a 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -32,8 +32,8 @@
/// A context in which a single analysis can be performed and incrementally
/// maintained. The context includes such information as the version of the SDK
-/// being analyzed against as well as the package-root used to resolve 'package:'
-/// URI's. (Both of which are known indirectly through the [SourceFactory].)
+/// being analyzed against, and how to resolve 'package:' URI's. (Both of which
+/// are known indirectly through the [SourceFactory].)
///
/// An analysis context also represents the state of the analysis, which includes
/// knowing which sources have been included in the analysis (either directly or
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index bd06d29..02f3df6 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2018,7 +2018,7 @@
TypeName typeName,
InterfaceType type) {
if (type.element.isAbstract && !type.element.isMixin) {
- ConstructorElement element = expression.staticElement;
+ ConstructorElement element = expression.constructorName.staticElement;
if (element != null && !element.isFactory) {
bool isImplicit =
(expression as InstanceCreationExpressionImpl).isImplicit;
@@ -2071,7 +2071,8 @@
* See [CompileTimeErrorCode.CONST_WITH_NON_CONST].
*/
void _checkForConstWithNonConst(InstanceCreationExpression expression) {
- ConstructorElement constructorElement = expression.staticElement;
+ ConstructorElement constructorElement =
+ expression.constructorName.staticElement;
if (constructorElement != null && !constructorElement.isConst) {
if (expression.keyword != null) {
_errorReporter.reportErrorForToken(
@@ -2100,7 +2101,7 @@
ConstructorName constructorName,
TypeName typeName) {
// OK if resolved
- if (expression.staticElement != null) {
+ if (constructorName.staticElement != null) {
return;
}
DartType type = typeName.type;
@@ -3497,7 +3498,7 @@
ConstructorName constructorName,
TypeName typeName) {
// OK if resolved
- if (expression.staticElement != null) {
+ if (constructorName.staticElement != null) {
return;
}
DartType type = typeName.type;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 028e2b2a..dd2cc51 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -362,17 +362,14 @@
_tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) {
afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType);
}
- if (afterReturnType == null) {
- // There was no return type, but it is optional, so go back to where we
- // started.
- afterReturnType = _currentToken;
- }
+ // If there was no return type, because it was optional, go back
+ // to where we started.
+ afterReturnType ??= _currentToken;
Token afterIdentifier = skipSimpleIdentifier(afterReturnType);
- if (afterIdentifier == null) {
- // It's possible that we parsed the function name as if it were a type
- // name, so see whether it makes sense if we assume that there is no type.
- afterIdentifier = skipSimpleIdentifier(_currentToken);
- }
+
+ // It's possible that we parsed the function name as if it were a type
+ // name, so see whether it makes sense if we assume that there is no type.
+ afterIdentifier ??= skipSimpleIdentifier(_currentToken);
if (afterIdentifier == null) {
return false;
}
@@ -407,9 +404,7 @@
return false;
}
Token afterTypeParameters = _skipTypeParameterList(token);
- if (afterTypeParameters == null) {
- afterTypeParameters = token;
- }
+ afterTypeParameters ??= token;
Token afterParameters = _skipFormalParameterList(afterTypeParameters);
if (afterParameters == null) {
return false;
@@ -2066,12 +2061,8 @@
getAndAdvance()));
} else if (!_matchesIdentifier()) {
Token keyword = modifiers.varKeyword;
- if (keyword == null) {
- keyword = modifiers.finalKeyword;
- }
- if (keyword == null) {
- keyword = modifiers.constKeyword;
- }
+ keyword ??= modifiers.finalKeyword;
+ keyword ??= modifiers.constKeyword;
if (keyword != null) {
//
// We appear to have found an incomplete top-level variable declaration.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index bdcf56f..7062807 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1794,7 +1794,6 @@
);
constructorElement = toLegacyElement(constructorElement);
constructor.staticElement = constructorElement;
- node.staticElement = constructor.staticElement;
}
}
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index fe2d430..3645309 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -137,18 +137,12 @@
@override
String get encoding {
- if (_encoding == null) {
- _encoding = uri.toString();
- }
- return _encoding;
+ return _encoding ??= uri.toString();
}
@override
String get fullName {
- if (_absolutePath == null) {
- _absolutePath = file.getAbsolutePath();
- }
- return _absolutePath;
+ return _absolutePath ??= file.getAbsolutePath();
}
@override
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 12dd347..2b0e133 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -664,15 +664,11 @@
*/
void _analyzeLeastUpperBoundTypes(
Expression node, DartType staticType1, DartType staticType2) {
- if (staticType1 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType1 = _dynamicType;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType1 ??= _dynamicType;
- if (staticType2 == null) {
- // TODO(brianwilkerson) Determine whether this can still happen.
- staticType2 = _dynamicType;
- }
+ // TODO(brianwilkerson) Determine whether this can still happen.
+ staticType2 ??= _dynamicType;
DartType staticType =
_typeSystem.getLeastUpperBound(staticType1, staticType2) ??
@@ -823,7 +819,6 @@
);
constructorElement = _resolver.toLegacyElement(constructorElement);
constructor.staticElement = constructorElement;
- node.staticElement = constructor.staticElement;
}
}
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 1833961..90c08eb 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -36,10 +36,7 @@
static InterfaceType _objectType;
static ClassElementImpl get object {
- if (_objectElement == null) {
- _objectElement = classElement("Object", null);
- }
- return _objectElement;
+ return _objectElement ??= classElement("Object", null);
}
static InterfaceType get objectType {
@@ -103,9 +100,7 @@
NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
CompilationUnitElementImpl unit = CompilationUnitElementImpl();
unit.source = source;
- if (librarySource == null) {
- librarySource = source;
- }
+ librarySource ??= source;
unit.librarySource = librarySource;
return unit;
}
@@ -402,8 +397,7 @@
static FunctionElementImpl functionElementWithParameters(String functionName,
DartType returnType, List<ParameterElement> parameters) {
FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
- functionElement.returnType =
- returnType == null ? VoidTypeImpl.instance : returnType;
+ functionElement.returnType = returnType ?? VoidTypeImpl.instance;
functionElement.parameters = parameters;
return functionElement;
}
@@ -610,7 +604,6 @@
Keyword.CONST, AstTestFactory.typeName(type.element));
if (type is InterfaceType) {
ConstructorElement element = type.element.unnamedConstructor;
- initializer.staticElement = element;
initializer.constructorName.staticElement = element;
}
constant.constantInitializer = initializer;
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 7ea5feb..35a0852 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -82,6 +81,7 @@
String packageConfigPath;
/// The path to the package root.
+ @Deprecated('https://github.com/dart-lang/sdk/issues/41197')
String packageRootPath;
/// Whether to use Dart's Strong Mode analyzer.
@@ -126,7 +126,6 @@
List<UriResolver> get resolvers {
// TODO(brianwilkerson) Use the context builder to compute all of the resolvers.
ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
- ContextBuilder builder = ContextBuilder(resourceProvider, null, null);
DartSdk sdk = options.mockSdk ??
FolderBasedDartSdk(
@@ -134,17 +133,6 @@
List<UriResolver> resolvers = [DartUriResolver(sdk)];
- if (options.packageRootPath != null) {
- builder.builderOptions.defaultPackagesDirectoryPath =
- options.packageRootPath;
- var packages = builder.createPackageMap(null);
- var packageMap = <String, List<Folder>>{};
- for (var package in packages.packages) {
- packageMap[package.name] = [package.libFolder];
- }
- resolvers.add(PackageMapUriResolver(resourceProvider, packageMap));
- }
-
var packageUriResolver = _getPackageUriResolver();
if (packageUriResolver != null) {
resolvers.add(packageUriResolver);
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 783cf74..86ecb8a 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -417,7 +417,7 @@
//
// Verify that the invoked constructor is a const constructor.
//
- ConstructorElement element = node.staticElement;
+ ConstructorElement element = node.constructorName.staticElement;
if (element == null || !element.isConst) {
return false;
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index c36c2ed..b029847 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -1048,7 +1048,6 @@
),
typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
);
- node.staticElement = node.constructorName.staticElement;
node.staticType = _readType(data.expression_type);
return node;
}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index df2cc09..06cc17d 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -231,7 +231,7 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
- var element = node.staticElement?.declaration;
+ var element = node.constructorName.staticElement?.declaration;
if (element == null) return;
_set.add(element);
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 8d3f33e..c1afdb9 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -308,11 +308,8 @@
Set<String> _lintCodes;
Set<String> get lintCodes {
- if (_lintCodes == null) {
- _lintCodes = Set.from(
- Registry.ruleRegistry.rules.map((rule) => rule.name.toUpperCase()));
- }
- return _lintCodes;
+ return _lintCodes ??= Set.from(
+ Registry.ruleRegistry.rules.map((rule) => rule.name.toUpperCase()));
}
@override
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 7f5b2d4..6492436 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -426,9 +426,9 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
var arguments = node.argumentList;
- var element = node.staticElement;
+ var element = node.constructorName.staticElement;
if (element != null) {
- var type = _elementType(node.staticElement);
+ var type = _elementType(element);
checkArgumentList(arguments, type);
}
node.visitChildren(this);
@@ -966,7 +966,7 @@
}
if (expr is InstanceCreationExpression) {
- ConstructorElement e = expr.staticElement;
+ ConstructorElement e = expr.constructorName.staticElement;
if (e == null || !e.isFactory) {
// fromT should be an exact type - this will almost certainly fail at
// runtime.
@@ -1193,7 +1193,7 @@
@override
visitInstanceCreationExpression(InstanceCreationExpression node) {
- var constructor = node.staticElement;
+ var constructor = node.constructorName.staticElement;
ClassElement class_ = constructor?.enclosingElement;
if (node.constructorName.type.typeArguments == null &&
class_ != null &&
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 91272fa..25dcc7d 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -77,7 +77,7 @@
unit.accept(FunctionAstVisitor(
functionDeclarationStatement: (node) {
var element = node.functionDeclaration.declaredElement;
- if (element is FunctionElement) {
+ if (element is FunctionElement && element.name == name) {
if (result != null) {
throw StateError('Not unique: $name');
}
@@ -212,6 +212,10 @@
}
}
+ for (var type in unitElement.functions) {
+ findIn(type.typeParameters);
+ }
+
for (var type in unitElement.functionTypeAliases) {
findIn(type.typeParameters);
if (type is GenericTypeAliasElement) {
diff --git a/pkg/analyzer/lib/src/workspace/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart
index fcef98c..62482bd 100644
--- a/pkg/analyzer/lib/src/workspace/gn.dart
+++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -47,7 +47,7 @@
/**
* The map from a package name to the list of its `lib/` folders.
*/
- Map<String, List<Folder>> _packageMap;
+ final Map<String, List<Folder>> _packageMap;
GnWorkspace._(this.provider, this.root, this._packageMap);
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index c4efa4a..2df2529 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -643,7 +643,6 @@
InstanceCreationExpression creation =
AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
_resolveNode(creation);
- expect(creation.staticElement, same(constructor));
_listener.assertNoErrors();
}
@@ -659,7 +658,6 @@
InstanceCreationExpression creation =
AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
_resolveNode(creation);
- expect(creation.staticElement, same(constructor));
_listener.assertNoErrors();
}
@@ -681,7 +679,6 @@
AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
]);
_resolveNode(creation);
- expect(creation.staticElement, same(constructor));
expect(
(creation.argumentList.arguments[0] as NamedExpression)
.name
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 03839d8..4e183c3 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -481,7 +481,6 @@
null,
AstTestFactory.typeName(classElement),
[AstTestFactory.identifier3(constructorName)]);
- node.staticElement = constructor;
expect(_analyze(node), interfaceTypeStar(classElement));
_listener.assertNoErrors();
}
@@ -499,7 +498,6 @@
typeArguments: [interfaceTypeStar(elementI)]);
InstanceCreationExpression node =
AstTestFactory.instanceCreationExpression2(null, typeName);
- node.staticElement = constructor;
InterfaceType type = _analyze(node) as InterfaceType;
List<DartType> typeArgs = type.typeArguments;
expect(typeArgs.length, 1);
@@ -516,7 +514,6 @@
InstanceCreationExpression node =
AstTestFactory.instanceCreationExpression2(
null, AstTestFactory.typeName(classElement));
- node.staticElement = constructor;
expect(_analyze(node), interfaceTypeStar(classElement));
_listener.assertNoErrors();
}
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 35ea5c4..2f7f926 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -18,7 +18,7 @@
@override
final SourceFactory sourceFactory = _MockSourceFactory();
- _MockAnalysisSession _analysisSession = _MockAnalysisSession();
+ final _MockAnalysisSession _analysisSession = _MockAnalysisSession();
AnalysisOptionsImpl _analysisOptions;
TypeProvider _typeProviderLegacy;
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
index 9e2a63c..362cc48 100644
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ b/pkg/analyzer/test/src/command_line/arguments_test.dart
@@ -24,7 +24,6 @@
String dartSdkSummaryPath = 'a';
String defaultAnalysisOptionsFilePath = 'b';
String defaultPackageFilePath = 'c';
- String defaultPackagesDirectoryPath = 'd';
ArgParser parser = ArgParser();
defineAnalysisArguments(parser);
List<String> args = [
@@ -35,7 +34,6 @@
'--no-implicit-dynamic',
'--options=$defaultAnalysisOptionsFilePath',
'--packages=$defaultPackageFilePath',
- '--package-root=$defaultPackagesDirectoryPath',
];
ArgResults result = parse(resourceProvider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
@@ -48,7 +46,6 @@
expect(
options.defaultAnalysisOptionsFilePath, defaultAnalysisOptionsFilePath);
expect(options.defaultPackageFilePath, defaultPackageFilePath);
- expect(options.defaultPackagesDirectoryPath, defaultPackagesDirectoryPath);
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
expect(defaultOptions.strongMode, true);
@@ -67,7 +64,6 @@
expect(options.declaredVariables, isEmpty);
expect(options.defaultAnalysisOptionsFilePath, isNull);
expect(options.defaultPackageFilePath, isNull);
- expect(options.defaultPackagesDirectoryPath, isNull);
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
expect(defaultOptions.strongMode, true);
@@ -129,7 +125,7 @@
void test_defineAnalysisArguments() {
ArgParser parser = ArgParser();
defineAnalysisArguments(parser);
- expect(parser.options, hasLength(12));
+ expect(parser.options, hasLength(11));
}
void test_extractDefinedVariables() {
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 7ebbad5..227862f 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -244,52 +244,6 @@
_expectEqualOptions(options, AnalysisOptionsImpl());
}
- void test_createPackageMap_fromPackageDirectory_explicit() {
- // Use a package directory that is outside the project directory.
- String rootPath = convertPath('/root');
- String projectPath = join(rootPath, 'project');
- String packageDirPath = join(rootPath, 'packages');
- String fooName = 'foo';
- String fooPath = join(packageDirPath, fooName);
- String barName = 'bar';
- String barPath = join(packageDirPath, barName);
- newFolder(projectPath);
- newFolder(fooPath);
- newFolder(barPath);
-
- builderOptions.defaultPackagesDirectoryPath = packageDirPath;
-
- Packages packages = builder.createPackageMap(projectPath);
- _assertPackages(
- packages,
- {
- 'foo': convertPath('/root/packages/foo/lib'),
- 'bar': convertPath('/root/packages/bar/lib'),
- },
- );
- }
-
- void test_createPackageMap_fromPackageDirectory_inRoot() {
- // Use a package directory that is inside the project directory.
- String projectPath = convertPath('/root/project');
- String packageDirPath = join(projectPath, 'packages');
- String fooName = 'foo';
- String fooPath = join(packageDirPath, fooName);
- String barName = 'bar';
- String barPath = join(packageDirPath, barName);
- newFolder(fooPath);
- newFolder(barPath);
-
- Packages packages = builder.createPackageMap(projectPath);
- _assertPackages(
- packages,
- {
- 'foo': convertPath('/root/project/packages/foo/lib'),
- 'bar': convertPath('/root/project/packages/bar/lib'),
- },
- );
- }
-
void test_createPackageMap_fromPackageFile_explicit() {
// Use a package file that is outside the project directory's hierarchy.
String rootPath = convertPath('/root');
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 7f8d145..e4a8348 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -669,11 +669,11 @@
expect(atD.name.staticElement, elementD);
expect(atD.element, constructorD);
- expect(constC.staticElement, constructorC);
expect(constC.staticType, interfaceTypeStar(elementC));
- expect(constC.constructorName.staticElement, constructorC);
- expect(constC.constructorName.type.type, interfaceTypeStar(elementC));
+ var constructorName = constC.constructorName;
+ expect(constructorName.staticElement, constructorC);
+ expect(constructorName.type.type, interfaceTypeStar(elementC));
}
test_annotation_unprefixed_topLevelVariable() async {
@@ -2039,36 +2039,36 @@
TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
VariableDeclaration aNode = aDeclaration.variables.variables[0];
InstanceCreationExpression value = aNode.initializer;
- expect(value.staticElement, defaultConstructor);
expect(value.staticType, interfaceTypeStar(cElement));
- TypeName typeName = value.constructorName.type;
+ var constructorName = value.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, defaultConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
-
- expect(value.constructorName.name, isNull);
}
{
TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
VariableDeclaration bNode = bDeclaration.variables.variables[0];
InstanceCreationExpression value = bNode.initializer;
- expect(value.staticElement, namedConstructor);
expect(value.staticType, interfaceTypeStar(cElement));
- TypeName typeName = value.constructorName.type;
+ var constructorName = value.constructorName;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
-
- SimpleIdentifier constructorName = value.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
}
}
@@ -2092,18 +2092,19 @@
InstanceCreationExpression creation = vNode.initializer;
List<Expression> arguments = creation.argumentList.arguments;
- expect(creation.staticElement, constructorElement);
expect(creation.staticType, interfaceTypeStar(xElement));
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, constructorElement);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, xElement);
expect(typeIdentifier.staticType, isNull);
- expect(creation.constructorName.name, isNull);
-
_assertArgumentToParameter(arguments[0], constructorElement.parameters[0]);
_assertArgumentToParameter(arguments[1], constructorElement.parameters[1]);
_assertArgumentToParameter(arguments[2], constructorElement.parameters[2]);
@@ -2132,18 +2133,19 @@
TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
VariableDeclaration aNode = aDeclaration.variables.variables[0];
InstanceCreationExpression value = aNode.initializer;
- expect(value.staticElement, defaultConstructor);
expect(value.staticType, interfaceTypeStar(cElement));
- TypeName typeName = value.constructorName.type;
+ var constructorName = value.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, defaultConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
- expect(value.constructorName.name, isNull);
-
Expression argument = value.argumentList.arguments[0];
_assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
}
@@ -2152,20 +2154,20 @@
TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
VariableDeclaration bNode = bDeclaration.variables.variables[0];
InstanceCreationExpression value = bNode.initializer;
- expect(value.staticElement, namedConstructor);
expect(value.staticType, interfaceTypeStar(cElement));
- TypeName typeName = value.constructorName.type;
+ var constructorName = value.constructorName;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.name.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
- SimpleIdentifier constructorName = value.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
-
Expression argument = value.argumentList.arguments[0];
_assertArgumentToParameter(argument, namedConstructor.parameters[0]);
}
@@ -2205,10 +2207,13 @@
ExpressionStatement statement = statements[0];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, defaultConstructor);
expect(creation.staticType, cTypeInt);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, defaultConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
PrefixedIdentifier typeIdentifier = typeName.name;
@@ -2221,8 +2226,6 @@
expect(typePrefix.staticType, isNull);
expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- expect(creation.constructorName.name, isNull);
}
{
@@ -2233,10 +2236,14 @@
ExpressionStatement statement = statements[1];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
expect(creation.staticType, cTypeDouble);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+ expect(constructorName.staticElement, namedConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
PrefixedIdentifier typeIdentifier = typeName.name;
@@ -2249,10 +2256,6 @@
expect(typePrefix.staticType, isNull);
expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
}
{
@@ -2263,10 +2266,14 @@
ExpressionStatement statement = statements[2];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
expect(creation.staticType, cTypeBool);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+ expect(constructorName.staticElement, namedConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments.arguments, hasLength(1));
_assertTypeNameSimple(
typeName.typeArguments.arguments[0], typeProvider.boolType);
@@ -2281,10 +2288,6 @@
expect(typePrefix.staticType, isNull);
expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
}
}
@@ -2319,17 +2322,18 @@
ExpressionStatement statement = statements[0];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, defaultConstructor);
expect(creation.staticType, cTypeInt);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, defaultConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, same(cElement));
expect(typeIdentifier.staticType, isNull);
-
- expect(creation.constructorName.name, isNull);
}
{
@@ -2340,10 +2344,13 @@
ExpressionStatement statement = statements[1];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, defaultConstructor);
expect(creation.staticType, cTypeBool);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name, isNull);
+ expect(constructorName.staticElement, defaultConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments.arguments, hasLength(1));
_assertTypeNameSimple(
typeName.typeArguments.arguments[0], typeProvider.boolType);
@@ -2351,8 +2358,6 @@
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, same(cElement));
expect(typeIdentifier.staticType, isNull);
-
- expect(creation.constructorName.name, isNull);
}
{
@@ -2363,21 +2368,19 @@
ExpressionStatement statement = statements[2];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
expect(creation.staticType, cTypeDouble);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+ expect(constructorName.staticElement, namedConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
-
- expect(typeIdentifier.staticElement, same(cElement));
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
}
{
@@ -2388,10 +2391,14 @@
ExpressionStatement statement = statements[3];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
expect(creation.staticType, cTypeBool);
- TypeName typeName = creation.constructorName.type;
+ var constructorName = creation.constructorName;
+ expect(constructorName.name.staticElement, namedConstructor);
+ expect(constructorName.name.staticType, isNull);
+ expect(constructorName.staticElement, namedConstructor);
+
+ TypeName typeName = constructorName.type;
expect(typeName.typeArguments.arguments, hasLength(1));
_assertTypeNameSimple(
typeName.typeArguments.arguments[0], typeProvider.boolType);
@@ -2399,10 +2406,6 @@
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
expect(typeIdentifier.staticType, isNull);
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
}
}
@@ -6407,7 +6410,10 @@
expect(access.staticType, typeProvider.intType);
InstanceCreationExpression newC = access.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
+ expect(
+ newC.constructorName.staticElement,
+ cClassElement.unnamedConstructor,
+ );
expect(newC.staticType, interfaceTypeStar(cClassElement));
expect(access.propertyName.staticElement, same(fElement.getter));
@@ -6441,7 +6447,10 @@
expect(access.staticType, typeProvider.intType);
InstanceCreationExpression newC = access.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
+ expect(
+ newC.constructorName.staticElement,
+ cClassElement.unnamedConstructor,
+ );
expect(newC.staticType, interfaceTypeStar(cClassElement));
expect(access.propertyName.staticElement, same(fElement.getter));
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 0333e83..8dfca61 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -1317,9 +1317,7 @@
ExpectedLocation _expectedLocation(String search, bool isQualified,
{int length}) {
int offset = findOffset(search);
- if (length == null) {
- length = getLeadingIdentifierLength(search);
- }
+ length ??= getLeadingIdentifierLength(search);
return ExpectedLocation(testUnitElement, offset, length, isQualified);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 1fe3cf2..c5d0487 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -9,11 +9,10 @@
import 'package:analyzer/dart/ast/ast.dart' hide Declaration;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/search.dart';
-import 'package:analyzer/src/dart/ast/element_locator.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -77,6 +76,9 @@
CompilationUnitElement testUnitElement;
LibraryElement testLibraryElement;
+ FindNode findNode;
+ FindElement findElement;
+
test_classMembers_class() async {
await _resolveTestUnit('''
class A {
@@ -90,8 +92,8 @@
}
}
''');
- ClassElement a = _findElement('A');
- ClassElement b = _findElement('B');
+ var a = findElement.class_('A');
+ var b = findElement.class_('B');
expect(await driver.search.classMembers('test'),
unorderedEquals([a.methods[0], b.fields[0]]));
}
@@ -116,8 +118,8 @@
}
}
''');
- ClassElement a = _findElement('A');
- ClassElement b = _findElement('B');
+ var a = findElement.mixin('A');
+ var b = findElement.mixin('B');
expect(await driver.search.classMembers('test'),
unorderedEquals([a.methods[0], b.fields[0]]));
}
@@ -146,7 +148,7 @@
p.test();
}
''');
- Element main = _findElement('main');
+ var main = findElement.function('main');
await _verifyNameReferences('test', <ExpectedResult>[
_expectIdQU(main, SearchResultKind.READ, 'test);'),
_expectIdQU(main, SearchResultKind.WRITE, 'test = 1;'),
@@ -181,7 +183,7 @@
}
}
''');
- Element main = _findElement('main');
+ var main = findElement.method('main');
await _verifyNameReferences('test', <ExpectedResult>[
_expectIdU(main, SearchResultKind.READ, 'test);'),
_expectIdU(main, SearchResultKind.WRITE, 'test = 1;'),
@@ -206,8 +208,8 @@
randomElement = result.unit.declaredElement.getType('Random');
}
- Element v1 = _findElement('v1');
- Element v2 = _findElement('v2');
+ var v1 = findElement.topVar('v1');
+ var v2 = findElement.topVar('v2');
var expected = [
_expectId(v1, SearchResultKind.REFERENCE, 'Random v1;'),
_expectId(v2, SearchResultKind.REFERENCE, 'Random v2;'),
@@ -222,8 +224,8 @@
Random v2;
''');
- var v1 = _findElement('v1') as VariableElement;
- var v2 = _findElement('v2') as VariableElement;
+ var v1 = findElement.topVar('v1');
+ var v2 = findElement.topVar('v2');
var randomElement = v1.type.element as ClassElement;
var expected = [
_expectId(v1, SearchResultKind.REFERENCE, 'Random v1;'),
@@ -243,13 +245,13 @@
class B3 extends Object with A {} // with
List<A> v2 = null;
''');
- ClassElement element = _findElementAtString('A {}');
- Element p = _findElement('p');
- Element main = _findElement('main');
- Element b1 = _findElement('B1');
- Element b2 = _findElement('B2');
- Element b3 = _findElement('B3');
- Element v2 = _findElement('v2');
+ var element = findElement.class_('A');
+ var p = findElement.parameter('p');
+ var main = findElement.function('main');
+ var b1 = findElement.class_('B1');
+ var b2 = findElement.class_('B2');
+ var b3 = findElement.class_('B3');
+ var v2 = findElement.topVar('v2');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'A p'),
_expectId(main, SearchResultKind.REFERENCE, 'A v'),
@@ -271,9 +273,9 @@
A v;
}
''');
- ClassElement element = _findElementAtString('A p');
- Element p = _findElement('p');
- Element main = _findElement('main');
+ var element = findNode.simple('A p').staticElement;
+ var p = findElement.parameter('p');
+ var main = findElement.function('main');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'A p'),
_expectId(main, SearchResultKind.REFERENCE, 'A v')
@@ -286,8 +288,8 @@
mixin A {}
class B extends Object with A {} // with
''');
- ClassElement element = _findElementAtString('A {}');
- Element b = _findElement('B');
+ var element = findElement.mixin('A');
+ var b = findElement.class_('B');
var expected = [
_expectId(b, SearchResultKind.REFERENCE, 'A {} // with'),
];
@@ -323,10 +325,10 @@
new A();
}
''');
- ConstructorElement element = _findElementAtString('A() {}');
- Element mainElement = _findElement('main');
+ var element = findElement.unnamedConstructor('A');
+ var main = findElement.function('main');
var expected = [
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, '();', length: 0)
+ _expectIdQ(main, SearchResultKind.REFERENCE, '();', length: 0)
];
await _verifyReferences(element, expected);
}
@@ -347,7 +349,7 @@
A() {}
}
''');
- ConstructorElement element = _findElementAtString('A() {}');
+ var element = findElement.unnamedConstructor('A');
CompilationUnit otherUnit = (await driver.getResult(other)).unit;
Element main = otherUnit.declaredElement.functions[0];
@@ -368,10 +370,10 @@
new A.named();
}
''');
- ConstructorElement element = _findElement('named');
- Element mainElement = _findElement('main');
+ var element = findElement.constructor('named');
+ var main = findElement.function('main');
var expected = [
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, '.named();',
+ _expectIdQ(main, SearchResultKind.REFERENCE, '.named();',
length: '.named'.length)
];
await _verifyReferences(element, expected);
@@ -385,11 +387,10 @@
new A();
}
''');
- ClassElement classElement = _findElement('A');
- ConstructorElement element = classElement.unnamedConstructor;
- Element mainElement = _findElement('main');
+ var element = findElement.unnamedConstructor('A');
+ var main = findElement.function('main');
var expected = [
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, '();', length: 0)
+ _expectIdQ(main, SearchResultKind.REFERENCE, '();', length: 0)
];
await _verifyReferences(element, expected);
}
@@ -412,9 +413,9 @@
}
}
''');
- FieldElement element = _findElement('field', ElementKind.FIELD);
- Element main = _findElement('main');
- Element fieldParameter = _findElement('field', ElementKind.PARAMETER);
+ var element = findElement.field('field');
+ var main = findElement.method('main');
+ var fieldParameter = findElement.parameter('field');
var expected = [
_expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'),
@@ -440,18 +441,18 @@
print(MyEnum.B);
}
''');
- ClassElement enumElement = _findElement('MyEnum');
- Element mainElement = _findElement('main');
+ var enumElement = findElement.enum_('MyEnum');
+ var main = findElement.function('main');
await _verifyReferences(enumElement.getField('index'),
- [_expectIdQ(mainElement, SearchResultKind.READ, 'index);')]);
+ [_expectIdQ(main, SearchResultKind.READ, 'index);')]);
await _verifyReferences(enumElement.getField('values'),
- [_expectIdQ(mainElement, SearchResultKind.READ, 'values);')]);
+ [_expectIdQ(main, SearchResultKind.READ, 'values);')]);
await _verifyReferences(enumElement.getField('A'), [
- _expectIdQ(mainElement, SearchResultKind.READ, 'A.index);'),
- _expectIdQ(mainElement, SearchResultKind.READ, 'A);')
+ _expectIdQ(main, SearchResultKind.READ, 'A.index);'),
+ _expectIdQ(main, SearchResultKind.READ, 'A);')
]);
await _verifyReferences(enumElement.getField('B'),
- [_expectIdQ(mainElement, SearchResultKind.READ, 'B);')]);
+ [_expectIdQ(main, SearchResultKind.READ, 'B);')]);
}
test_searchReferences_FieldElement_synthetic() async {
@@ -471,8 +472,8 @@
}
}
''');
- FieldElement element = _findElement('field', ElementKind.FIELD);
- Element main = _findElement('main');
+ var element = findElement.field('field');
+ var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
_expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
@@ -492,11 +493,11 @@
print(test);
}
''');
- FunctionElement element = _findElement('test');
- Element mainElement = _findElement('main');
+ var element = findElement.function('test');
+ var main = findElement.function('main');
var expected = [
- _expectId(mainElement, SearchResultKind.INVOCATION, 'test();'),
- _expectId(mainElement, SearchResultKind.REFERENCE, 'test);')
+ _expectId(main, SearchResultKind.INVOCATION, 'test();'),
+ _expectId(main, SearchResultKind.REFERENCE, 'test);')
];
await _verifyReferences(element, expected);
}
@@ -510,7 +511,7 @@
}
''');
FunctionElement element = findElementsByName(testUnit, 'test').single;
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.INVOCATION, 'test();'),
_expectId(main, SearchResultKind.REFERENCE, 'test);')
@@ -530,14 +531,14 @@
Random bar() => null;
''');
ImportElement element = testLibraryElement.imports[0];
- Element mainElement = _findElement('main');
- Element barElement = _findElement('bar');
+ var main = findElement.function('main');
+ var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var expected = [
- _expectId(mainElement, kind, 'PI);', length: 0),
- _expectId(mainElement, kind, 'Random()', length: 0),
- _expectId(mainElement, kind, 'max(', length: 0),
- _expectId(barElement, kind, 'Random bar()', length: 0),
+ _expectId(main, kind, 'PI);', length: 0),
+ _expectId(main, kind, 'Random()', length: 0),
+ _expectId(main, kind, 'max(', length: 0),
+ _expectId(bar, kind, 'Random bar()', length: 0),
];
await _verifyReferences(element, expected);
}
@@ -555,14 +556,14 @@
Random bar() => null;
''', addToDriver: false);
ImportElement element = testLibraryElement.imports[0];
- Element mainElement = _findElement('main');
- Element barElement = _findElement('bar');
+ var main = findElement.function('main');
+ var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var expected = [
- _expectId(mainElement, kind, 'PI;', length: 0),
- _expectId(mainElement, kind, 'Random();', length: 0),
- _expectId(mainElement, kind, 'max(1, 2);', length: 0),
- _expectId(barElement, kind, 'Random bar()', length: 0),
+ _expectId(main, kind, 'PI;', length: 0),
+ _expectId(main, kind, 'Random();', length: 0),
+ _expectId(main, kind, 'max(1, 2);', length: 0),
+ _expectId(bar, kind, 'Random bar()', length: 0),
];
await _verifyReferences(element, expected);
}
@@ -579,15 +580,15 @@
math.Random bar() => null;
''');
ImportElement element = testLibraryElement.imports[0];
- Element mainElement = _findElement('main');
- Element barElement = _findElement('bar');
+ var main = findElement.function('main');
+ var bar = findElement.function('bar');
var kind = SearchResultKind.REFERENCE;
var length = 'math.'.length;
var expected = [
- _expectId(mainElement, kind, 'math.PI);', length: length),
- _expectId(mainElement, kind, 'math.Random()', length: length),
- _expectId(mainElement, kind, 'math.max(', length: length),
- _expectId(barElement, kind, 'math.Random bar()', length: length),
+ _expectId(main, kind, 'math.PI);', length: length),
+ _expectId(main, kind, 'math.Random()', length: length),
+ _expectId(main, kind, 'math.max(', length: length),
+ _expectId(bar, kind, 'math.Random bar()', length: length),
];
await _verifyReferences(element, expected);
}
@@ -601,20 +602,20 @@
p.Future;
}
''');
- Element mainElement = _findElement('main');
+ var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var length = 'p.'.length;
{
ImportElement element = testLibraryElement.imports[0];
var expected = [
- _expectId(mainElement, kind, 'p.Future;', length: length),
+ _expectId(main, kind, 'p.Future;', length: length),
];
await _verifyReferences(element, expected);
}
{
ImportElement element = testLibraryElement.imports[1];
var expected = [
- _expectId(mainElement, kind, 'p.Random', length: length),
+ _expectId(main, kind, 'p.Random', length: length),
];
await _verifyReferences(element, expected);
}
@@ -633,7 +634,7 @@
}
''');
Element element = findElementsByName(testUnit, 'label').single;
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'label; // 1'),
_expectId(main, SearchResultKind.REFERENCE, 'label; // 2')
@@ -700,7 +701,7 @@
}
''');
Element element = findElementsByName(testUnit, 'v').single;
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
@@ -722,7 +723,7 @@
}
''');
Element element = findElementsByName(testUnit, 'v').single;
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'v += 2;'),
@@ -745,7 +746,7 @@
}
''', addToDriver: false);
Element element = findElementsByName(testUnit, 'v').single;
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'v = 1;'),
@@ -768,13 +769,13 @@
}
}
''');
- MethodElement method = _findElement('m');
- Element mainElement = _findElement('main');
+ var method = findElement.method('m');
+ var main = findElement.method('main');
var expected = [
- _expectId(mainElement, SearchResultKind.INVOCATION, 'm(); // 1'),
- _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // 2'),
- _expectId(mainElement, SearchResultKind.REFERENCE, 'm); // 3'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'm); // 4')
+ _expectId(main, SearchResultKind.INVOCATION, 'm(); // 1'),
+ _expectIdQ(main, SearchResultKind.INVOCATION, 'm(); // 2'),
+ _expectId(main, SearchResultKind.REFERENCE, 'm); // 3'),
+ _expectIdQ(main, SearchResultKind.REFERENCE, 'm); // 4')
];
await _verifyReferences(method, expected);
}
@@ -792,15 +793,15 @@
}
}
''');
- MethodElement method = _findElement('foo');
- Element mainElement = _findElement('bar');
+ var foo = findElement.method('foo');
+ var bar = findElement.method('bar');
var expected = [
- _expectId(mainElement, SearchResultKind.INVOCATION, 'foo(); // 1'),
- _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'foo(); // 2'),
- _expectId(mainElement, SearchResultKind.REFERENCE, 'foo); // 3'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'foo); // 4')
+ _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+ _expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
+ _expectId(bar, SearchResultKind.REFERENCE, 'foo); // 3'),
+ _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo); // 4')
];
- await _verifyReferences(method, expected);
+ await _verifyReferences(foo, expected);
}
test_searchReferences_MethodElement_extension_unnamed() async {
@@ -816,15 +817,15 @@
}
}
''');
- MethodElement method = _findElement('foo');
- Element mainElement = _findElement('bar');
+ var foo = findElement.method('foo');
+ var bar = findElement.method('bar');
var expected = [
- _expectId(mainElement, SearchResultKind.INVOCATION, 'foo(); // 1'),
- _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'foo(); // 2'),
- _expectId(mainElement, SearchResultKind.REFERENCE, 'foo); // 3'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'foo); // 4')
+ _expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
+ _expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
+ _expectId(bar, SearchResultKind.REFERENCE, 'foo); // 3'),
+ _expectIdQ(bar, SearchResultKind.REFERENCE, 'foo); // 4')
];
- await _verifyReferences(method, expected);
+ await _verifyReferences(foo, expected);
}
test_searchReferences_MethodMember_class() async {
@@ -836,10 +837,10 @@
a.m(); // ref
}
''');
- MethodMember method = _findElementAtString('m(); // ref');
- Element mainElement = _findElement('main');
+ var method = findElement.method('m');
+ var main = findElement.function('main');
var expected = [
- _expectIdQ(mainElement, SearchResultKind.INVOCATION, 'm(); // ref')
+ _expectIdQ(main, SearchResultKind.INVOCATION, 'm(); // ref')
];
await _verifyReferences(method, expected);
}
@@ -856,15 +857,15 @@
foo(p: 42);
}
''');
- ParameterElement element = _findElement('p');
- Element fooElement = _findElement('foo');
- Element mainElement = _findElement('main');
+ var element = findElement.parameter('p');
+ var foo = findElement.function('foo');
+ var main = findElement.function('main');
var expected = [
- _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
- _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, SearchResultKind.READ, 'p);'),
- _expectId(fooElement, SearchResultKind.READ, 'p();'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, 'p: 42')
+ _expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
+ _expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
+ _expectId(foo, SearchResultKind.READ, 'p);'),
+ _expectId(foo, SearchResultKind.READ, 'p();'),
+ _expectIdQ(main, SearchResultKind.REFERENCE, 'p: 42')
];
await _verifyReferences(element, expected);
}
@@ -884,15 +885,14 @@
new C(42);
}
''');
- ParameterElement element = _findElement('p');
- ClassElement classC = _findElement('C');
- ConstructorElement constructorA = classC.unnamedConstructor;
+ var element = findElement.parameter('p');
+ var constructor = findElement.unnamedConstructor('C');
var expected = [
- _expectId(constructorA, SearchResultKind.READ, 'p + 1 {'),
- _expectId(constructorA, SearchResultKind.WRITE, 'p = 2;'),
- _expectId(constructorA, SearchResultKind.READ_WRITE, 'p += 3;'),
- _expectId(constructorA, SearchResultKind.READ, 'p);'),
- _expectId(constructorA, SearchResultKind.READ, 'p();')
+ _expectId(constructor, SearchResultKind.READ, 'p + 1 {'),
+ _expectId(constructor, SearchResultKind.WRITE, 'p = 2;'),
+ _expectId(constructor, SearchResultKind.READ_WRITE, 'p += 3;'),
+ _expectId(constructor, SearchResultKind.READ, 'p);'),
+ _expectId(constructor, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
@@ -909,9 +909,8 @@
foo(42);
}
''');
- Element main = _findElement('main');
- FunctionElement foo = findElementsByName(testUnit, 'foo').single;
- ParameterElement element = foo.parameters.single;
+ var main = findElement.function('main');
+ var element = findElement.parameter('p');
var expected = [
_expectId(main, SearchResultKind.WRITE, 'p = 1;'),
_expectId(main, SearchResultKind.READ_WRITE, 'p += 2;'),
@@ -935,13 +934,13 @@
c.foo(42);
}
''');
- ParameterElement element = _findElement('p');
- Element fooElement = _findElement('foo');
+ var element = findElement.parameter('p');
+ var foo = findElement.method('foo');
var expected = [
- _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
- _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, SearchResultKind.READ, 'p);'),
- _expectId(fooElement, SearchResultKind.READ, 'p();')
+ _expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
+ _expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
+ _expectId(foo, SearchResultKind.READ, 'p);'),
+ _expectId(foo, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
@@ -958,13 +957,13 @@
foo(42);
}
''');
- ParameterElement element = _findElement('p');
- Element fooElement = _findElement('foo');
+ var element = findElement.parameter('p');
+ var foo = findElement.function('foo');
var expected = [
- _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
- _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, SearchResultKind.READ, 'p);'),
- _expectId(fooElement, SearchResultKind.READ, 'p();')
+ _expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
+ _expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
+ _expectId(foo, SearchResultKind.READ, 'p);'),
+ _expectId(foo, SearchResultKind.READ, 'p();')
];
await _verifyReferences(element, expected);
}
@@ -981,15 +980,15 @@
foo(42);
}
''');
- ParameterElement element = _findElement('p');
- Element fooElement = _findElement('foo');
- Element mainElement = _findElement('main');
+ var element = findElement.parameter('p');
+ var foo = findElement.function('foo');
+ var main = findElement.function('main');
var expected = [
- _expectId(fooElement, SearchResultKind.WRITE, 'p = 1;'),
- _expectId(fooElement, SearchResultKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, SearchResultKind.READ, 'p);'),
- _expectId(fooElement, SearchResultKind.READ, 'p();'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, '42', length: 0)
+ _expectId(foo, SearchResultKind.WRITE, 'p = 1;'),
+ _expectId(foo, SearchResultKind.READ_WRITE, 'p += 2;'),
+ _expectId(foo, SearchResultKind.READ, 'p);'),
+ _expectId(foo, SearchResultKind.READ, 'p();'),
+ _expectIdQ(main, SearchResultKind.REFERENCE, '42', length: 0)
];
await _verifyReferences(element, expected);
}
@@ -1009,8 +1008,8 @@
ppp.Stream b;
}
''');
- PrefixElement element = _findElementAtString('ppp;');
- Element main = _findElement('main');
+ var element = findElement.prefix('ppp');
+ var main = findElement.function('main');
Element c = findChildElement(testLibraryElement, 'c');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Future'),
@@ -1039,8 +1038,8 @@
ppp.Stream b;
}
''', addToDriver: false);
- PrefixElement element = _findElementAtString('ppp;');
- Element main = _findElement('main');
+ var element = findElement.prefix('ppp');
+ var main = findElement.function('main');
Element c = findChildElement(testLibraryElement, 'c');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ppp.Future'),
@@ -1073,7 +1072,7 @@
class _C {}
_C v;
''');
- ClassElement element = _findElementAtString('_C {}');
+ var element = findElement.class_('_C');
Element v = testUnitElement.topLevelVariables[0];
Element v1 = testLibraryElement.parts[0].topLevelVariables[0];
Element v2 = testLibraryElement.parts[1].topLevelVariables[0];
@@ -1178,8 +1177,8 @@
}
}
''');
- PropertyAccessorElement element = _findElement('ggg', ElementKind.GETTER);
- Element main = _findElement('main');
+ var element = findElement.getter('ggg');
+ var main = findElement.method('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'ggg); // ref-nq'),
_expectIdQ(main, SearchResultKind.REFERENCE, 'ggg); // ref-q'),
@@ -1199,11 +1198,11 @@
}
}
''');
- PropertyAccessorElement element = _findElement('s=');
- Element mainElement = _findElement('main');
+ var element = findElement.setter('s');
+ var main = findElement.method('main');
var expected = [
- _expectId(mainElement, SearchResultKind.REFERENCE, 's = 1'),
- _expectIdQ(mainElement, SearchResultKind.REFERENCE, 's = 2')
+ _expectId(main, SearchResultKind.REFERENCE, 's = 1'),
+ _expectIdQ(main, SearchResultKind.REFERENCE, 's = 2')
];
await _verifyReferences(element, expected);
}
@@ -1229,7 +1228,7 @@
CompilationUnitElement impUnit =
importElement.importedLibrary.definingCompilationUnit;
TopLevelVariableElement variable = impUnit.topLevelVariables[0];
- Element main = _findElement('main');
+ var main = findElement.function('main');
var expected = [
_expectIdQ(testUnitElement, SearchResultKind.REFERENCE, 'V; // imp'),
_expectIdQ(main, SearchResultKind.WRITE, 'V = 1; // q'),
@@ -1249,9 +1248,9 @@
bar(T b) {}
}
''');
- TypeParameterElement element = _findElement('T');
- Element a = _findElement('a');
- Element b = _findElement('b');
+ var element = findElement.typeParameter('T');
+ var a = findElement.parameter('a');
+ var b = findElement.parameter('b');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T a'),
_expectId(b, SearchResultKind.REFERENCE, 'T b'),
@@ -1267,9 +1266,9 @@
}
}
''');
- Element main = _findElement('main');
- FunctionElement foo = findElementsByName(testUnit, 'foo').single;
- TypeParameterElement element = foo.typeParameters.single;
+ var main = findElement.function('main');
+ var foo = findElement.localFunction('foo');
+ var element = foo.typeParameters.single;
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'T a'),
_expectId(main, SearchResultKind.REFERENCE, 'T b'),
@@ -1283,8 +1282,8 @@
foo<T>(T p) {}
}
''');
- TypeParameterElement element = _findElement('T');
- Element p = _findElement('p');
+ var element = findElement.typeParameter('T');
+ var p = findElement.parameter('p');
var expected = [
_expectId(p, SearchResultKind.REFERENCE, 'T p'),
];
@@ -1297,9 +1296,9 @@
bar(T b) {}
}
''');
- FunctionElement foo = _findElement('foo');
- TypeParameterElement element = _findElement('T');
- Element a = _findElement('a');
+ var foo = findElement.function('foo');
+ var element = findElement.typeParameter('T');
+ var a = findElement.parameter('a');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T a'),
_expectId(foo, SearchResultKind.REFERENCE, 'T b'),
@@ -1314,10 +1313,10 @@
class B = Object with T; // B
class C implements T {} // C
''');
- ClassElement element = _findElement('T');
- ClassElement a = _findElement('A');
- ClassElement b = _findElement('B');
- ClassElement c = _findElement('C');
+ var element = findElement.class_('T');
+ var a = findElement.class_('A');
+ var b = findElement.class_('B');
+ var c = findElement.class_('C');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T {} // A'),
_expectId(b, SearchResultKind.REFERENCE, 'T; // B'),
@@ -1332,9 +1331,9 @@
mixin A on T {} // A
mixin B implements T {} // B
''');
- ClassElement element = _findElement('T');
- ClassElement a = _findElement('A');
- ClassElement b = _findElement('B');
+ var element = findElement.class_('T');
+ var a = findElement.mixin('A');
+ var b = findElement.mixin('B');
var expected = [
_expectId(a, SearchResultKind.REFERENCE, 'T {} // A'),
_expectId(b, SearchResultKind.REFERENCE, 'T {} // B'),
@@ -1364,7 +1363,7 @@
class F {}
''');
- ClassElement a = _findElement('A');
+ var a = findElement.class_('A');
// Search by 'type'.
List<SubtypeResult> subtypes =
@@ -1509,7 +1508,7 @@
await _resolveTestUnit('''
class A {}
''');
- ClassElement a = _findElement('A');
+ var a = findElement.class_('A');
driver.addFile(pathB);
driver.addFile(pathC);
@@ -1541,8 +1540,8 @@
void methodM() {}
}
''');
- ClassElement a = _findElement('A');
- ClassElement b = _findElement('B');
+ var a = findElement.class_('A');
+ var b = findElement.class_('B');
{
var subtypes = await driver.search.subtypes(SearchedFiles(), type: a);
@@ -1572,7 +1571,7 @@
class A {}
class B extends A {}
''');
- ClassElement a = _findElement('A');
+ var a = findElement.class_('A');
List<SubtypeResult> subtypes =
await driver.search.subtypes(SearchedFiles(), type: a);
@@ -1593,12 +1592,12 @@
var f = null;
class NoMatchABCDEF {}
''');
- Element a = _findElement('A');
- Element b = _findElement('B');
- Element c = _findElement('C');
- Element d = _findElement('D');
- Element e = _findElement('e');
- Element f = _findElement('f');
+ var a = findElement.class_('A');
+ var b = findElement.class_('B');
+ var c = findElement.mixin('C');
+ var d = findElement.functionTypeAlias('D');
+ var e = findElement.function('e');
+ var f = findElement.topVar('f');
RegExp regExp = RegExp(r'^[ABCDef]$');
expect(await driver.search.topLevelElements(regExp),
unorderedEquals([a, b, c, d, e, f]));
@@ -1608,9 +1607,7 @@
Element enclosingElement, SearchResultKind kind, String search,
{int length, bool isResolved = true, bool isQualified = false}) {
int offset = findOffset(search);
- if (length == null) {
- length = getLeadingIdentifierLength(search);
- }
+ length ??= getLeadingIdentifierLength(search);
return ExpectedResult(enclosingElement, kind, offset, length,
isResolved: isResolved, isQualified: isQualified);
}
@@ -1644,16 +1641,6 @@
isQualified: false, isResolved: false, length: length);
}
- Element _findElement(String name, [ElementKind kind]) {
- return findChildElement(testUnit.declaredElement, name, kind);
- }
-
- Element _findElementAtString(String search) {
- int offset = findOffset(search);
- AstNode node = NodeLocator(offset).searchWithin(testUnit);
- return ElementLocator.locate(node);
- }
-
Future<void> _resolveTestUnit(String code, {bool addToDriver = true}) async {
if (addToDriver) {
addTestFile(code);
@@ -1666,6 +1653,9 @@
testUnit = result.unit;
testUnitElement = testUnit.declaredElement;
testLibraryElement = testUnitElement.library;
+
+ findNode = FindNode(result.content, result.unit);
+ findElement = FindElement(result.unit);
}
}
@@ -1711,8 +1701,8 @@
E.bar();
}
''');
- var element = _findElement('E');
- var main = _findElement('main');
+ var element = findElement.extension_('E');
+ var main = findElement.function('main');
var expected = [
_expectId(main, SearchResultKind.REFERENCE, 'E(0)'),
_expectId(main, SearchResultKind.REFERENCE, 'E.bar()'),
@@ -1740,9 +1730,9 @@
0.foo; // 8
}
''');
- var element = _findElement('foo');
- var bar = _findElement('bar');
- var main = _findElement('main');
+ var element = findElement.method('foo');
+ var bar = findElement.method('bar');
+ var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectIdQ(bar, SearchResultKind.INVOCATION, 'foo(); // 2'),
@@ -1772,9 +1762,9 @@
E.foo; // 4
}
''');
- var element = _findElement('foo');
- var bar = _findElement('bar');
- var main = _findElement('main');
+ var element = findElement.method('foo');
+ var bar = findElement.method('bar');
+ var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.INVOCATION, 'foo(); // 1'),
_expectId(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
@@ -1800,9 +1790,9 @@
0.foo; // 4
}
''');
- var element = _findElement('foo', ElementKind.GETTER);
- var bar = _findElement('bar');
- var main = _findElement('main');
+ var element = findElement.getter('foo');
+ var bar = findElement.method('bar');
+ var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.REFERENCE, 'foo; // 1'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo; // 2'),
@@ -1828,9 +1818,9 @@
0.foo = 4;
}
''');
- var element = _findElement('foo=');
- var bar = _findElement('bar');
- var main = _findElement('main');
+ var element = findElement.setter('foo');
+ var bar = findElement.method('bar');
+ var main = findElement.function('main');
var expected = [
_expectId(bar, SearchResultKind.REFERENCE, 'foo = 1;'),
_expectIdQ(bar, SearchResultKind.REFERENCE, 'foo = 2;'),
@@ -1868,13 +1858,13 @@
}
''');
ImportElement element = testLibraryElement.imports[0];
- Element mainElement = _findElement('main');
+ var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var expected = [
- _expectId(mainElement, kind, 'N1;', length: 0),
- _expectId(mainElement, kind, 'N2();', length: 0),
- _expectId(mainElement, kind, 'N3;', length: 0),
- _expectId(mainElement, kind, 'N4 =', length: 0),
+ _expectId(main, kind, 'N1;', length: 0),
+ _expectId(main, kind, 'N2();', length: 0),
+ _expectId(main, kind, 'N3;', length: 0),
+ _expectId(main, kind, 'N4 =', length: 0),
];
await _verifyReferences(element, expected);
}
@@ -1899,14 +1889,14 @@
}
''');
ImportElement element = testLibraryElement.imports[0];
- Element mainElement = _findElement('main');
+ var main = findElement.function('main');
var kind = SearchResultKind.REFERENCE;
var length = 'a.'.length;
var expected = [
- _expectId(mainElement, kind, 'a.N1;', length: length),
- _expectId(mainElement, kind, 'a.N2()', length: length),
- _expectId(mainElement, kind, 'a.N3', length: length),
- _expectId(mainElement, kind, 'a.N4', length: length),
+ _expectId(main, kind, 'a.N1;', length: length),
+ _expectId(main, kind, 'a.N2()', length: length),
+ _expectId(main, kind, 'a.N3', length: length),
+ _expectId(main, kind, 'a.N4', length: length),
];
await _verifyReferences(element, expected);
}
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 441a8ff..1489f45 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -520,14 +520,14 @@
Keyword.NEW, AstTestFactory.typeName4("C"));
ConstructorElement staticElement = ElementFactory.constructorElement2(
ElementFactory.classElement2("C"), null);
- fromNode.staticElement = staticElement;
+ fromNode.constructorName.staticElement = staticElement;
DartType staticType = interfaceTypeStar(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
InstanceCreationExpression toNode =
AstTestFactory.instanceCreationExpression2(
Keyword.NEW, AstTestFactory.typeName4("C"));
ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.staticElement, same(staticElement));
+ expect(toNode.constructorName.staticElement, same(staticElement));
expect(toNode.staticType, same(staticType));
}
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
index 4354565..c0e9cc7 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -4,16 +4,13 @@
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/element/generic_inferrer.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:meta/meta.dart';
import 'package:path/path.dart' show toUri;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -22,609 +19,11 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ConstraintMatchingTest);
defineReflectiveTests(GenericFunctionInferenceTest);
});
}
@reflectiveTest
-class ConstraintMatchingTest extends AbstractTypeSystemNullSafetyTest {
- TypeParameterElement T;
- TypeParameterType T_none;
- TypeParameterType T_question;
-
- @override
- void setUp() {
- super.setUp();
- T = typeParameter('T');
- T_none = typeParameterTypeNone(T);
- T_question = typeParameterTypeQuestion(T);
- }
-
- void test_function_coreFunction() {
- _checkOrdinarySubtypeMatch(
- functionTypeNone(
- returnType: voidNone,
- ),
- typeProvider.functionType,
- [T],
- covariant: true,
- );
- }
-
- void test_function_parameters_requiredPositional() {
- _checkIsSubtypeMatchOf(
- functionTypeNone(
- parameters: [
- requiredParameter(type: T_none),
- ],
- returnType: intNone,
- ),
- functionTypeNone(
- parameters: [
- requiredParameter(type: stringNone),
- ],
- returnType: intNone,
- ),
- [T],
- ['String <: T'],
- covariant: true,
- );
- }
-
- void test_function_returnType() {
- _checkIsSubtypeMatchOf(
- functionTypeNone(
- parameters: [
- requiredParameter(type: intNone),
- ],
- returnType: T_none,
- ),
- functionTypeNone(
- parameters: [
- requiredParameter(type: intNone),
- ],
- returnType: stringNone,
- ),
- [T],
- ['T <: String'],
- covariant: true,
- );
- }
-
- /// Left FutureOr: if `T0` is `FutureOr<S0>` then:
- /// * `T0 <: T1` iff `Future<S0> <: T1` and `S0 <: T1`
- void test_futureOr_left() {
- _checkIsSubtypeMatchOf(
- futureOrNone(T_none),
- futureOrNone(stringNone),
- [T],
- ['T <: String'],
- covariant: true,
- );
-
- _checkIsSubtypeMatchOf(
- futureOrNone(T_none),
- futureNone(stringNone),
- [T],
- ['T <: String', 'T <: Future<String>'],
- covariant: true,
- );
-
- // Future<List<T>> <: List<String> can't be satisfied
- _checkIsNotSubtypeMatchOf(
- futureOrNone(listNone(T_none)),
- listNone(stringNone),
- [T],
- covariant: true,
- );
-
- // List<T> <: Future<List<String>> can't be satisfied
- _checkIsNotSubtypeMatchOf(
- futureOrNone(listNone(T_none)),
- futureNone(listNone(stringNone)),
- [T],
- covariant: true,
- );
- }
-
- void test_futureOr_right_both_noConstraints() {
- // `Future<String> <: Future<Object>` can be satisfied:
- // * no constraints
- //
- // `Future<String> <: Object` can be satisfied:
- // * no constraints
- _checkIsSubtypeMatchOf(
- futureNone(stringNone),
- futureOrNone(objectNone),
- [T],
- [],
- covariant: true,
- );
- }
-
- void test_futureOr_right_both_prefer_future() {
- // `Future<String> <: Future<T>` can be satisfied:
- // * `String <: T`
- //
- // `Future<String> <: T` can be satisfied:
- // * `Future<String> <: T`
- //
- // We prefer `String <: T`.
- _checkIsSubtypeMatchOf(
- futureNone(stringNone),
- futureOrNone(T_none),
- [T],
- ['String <: T'],
- covariant: false,
- );
-
- // `Future<T> <: Future<Object>` can be satisfied:
- // * `T <: Object`
- //
- // `Future<T> <: Object` can be satisfied:
- // * no constraints
- //
- // We prefer `T <: Object`.
- _checkIsSubtypeMatchOf(
- futureNone(T_none),
- futureOrNone(objectNone),
- [T],
- ['T <: Object'],
- covariant: true,
- );
- }
-
- /// Right FutureOr: if `T1` is `FutureOr<S1>` then:
- /// `T0 <: T1` iff any of the following hold:
- /// * either `T0 <: Future<S1>`
- /// * or `T0 <: S1`
- void test_futureOr_right_none() {
- // `List<T> <: Future<String>` cannot be satisfied.
- // `List<T> <: int` cannot be satisfied.
- _checkIsNotSubtypeMatchOf(
- listNone(T_none),
- futureOrNone(stringNone),
- [T],
- covariant: true,
- );
- }
-
- void test_futureOr_right_single_future() {
- // `Future<T> <: Future<String>` can be satisfied:
- // * `T <: String`
- //
- // `Future<T> <: String` cannot be satisfied.
- _checkIsSubtypeMatchOf(
- futureNone(T_none),
- futureOrNone(stringNone),
- [T],
- ['T <: String'],
- covariant: true,
- );
- }
-
- void test_futureOr_right_single_nonFuture() {
- // `List<T> <: Future<List<String>>` cannot be satisfied.
- //
- // `List<T> <: List<String>` can be satisfied:
- // * `T <: String`
- _checkIsSubtypeMatchOf(
- listNone(T_none),
- futureOrNone(listNone(stringNone)),
- [T],
- ['T <: String'],
- covariant: true,
- );
- }
-
- void test_futureOr_right_single_nonFuture_null() {
- // `Null <: Future<T>` can be satisfied:
- // * no constraints
- //
- // `Null <: T` can be satisfied:
- // * `Null <: T`
- //
- // We prefer `Null <: T`.
- _checkIsSubtypeMatchOf(
- nullNone,
- futureOrNone(T_none),
- [T],
- ['Null <: T'],
- covariant: false,
- );
- }
-
- void test_interfaceType_interface_left() {
- _checkIsNotSubtypeMatchOf(
- iterableNone(T_none),
- listNone(stringNone),
- [T],
- covariant: true,
- );
- }
-
- void test_interfaceType_interface_right() {
- _checkIsSubtypeMatchOf(
- listNone(T_none),
- iterableNone(stringNone),
- [T],
- ['T <: String'],
- covariant: true,
- );
- }
-
- void test_interfaceType_sameClass() {
- _checkIsSubtypeMatchOf(
- listNone(T_none),
- listNone(stringNone),
- [T],
- ['T <: String'],
- covariant: true,
- );
- }
-
- void test_interfaceType_topMerge() {
- var testClassIndex = 0;
-
- void check1(
- DartType extendsTypeArgument,
- DartType implementsTypeArgument,
- String expectedConstraint,
- ) {
- var library = library_(
- uriStr: 'package:test/test.dart',
- analysisSession: analysisContext.analysisSession,
- typeSystem: typeSystem,
- );
-
- // class A<T> {}
- var A = class_(name: 'A', typeParameters: [
- typeParameter('T'),
- ]);
- A.enclosingElement = library.definingCompilationUnit;
-
- // class B<T> extends A<T> {}
- var B_T = typeParameter('T');
- var B_T_none = typeParameterTypeNone(B_T);
- var B = class_(
- name: 'B',
- typeParameters: [B_T],
- superType: interfaceTypeNone(A, typeArguments: [B_T_none]),
- );
- B.enclosingElement = library.definingCompilationUnit;
-
- // class Cx extends A<> implements B<> {}
- var C = class_(
- name: 'C${testClassIndex++}',
- superType: interfaceTypeNone(
- A,
- typeArguments: [extendsTypeArgument],
- ),
- interfaces: [
- interfaceTypeNone(
- B,
- typeArguments: [implementsTypeArgument],
- )
- ],
- );
- C.enclosingElement = library.definingCompilationUnit;
-
- _checkIsSubtypeMatchOf(
- interfaceTypeNone(C),
- interfaceTypeNone(A, typeArguments: [T_none]),
- [T],
- [expectedConstraint],
- covariant: false,
- );
- }
-
- void check(
- DartType typeArgument1,
- DartType typeArgument2,
- String expectedConstraint,
- ) {
- check1(typeArgument1, typeArgument2, expectedConstraint);
- check1(typeArgument2, typeArgument1, expectedConstraint);
- }
-
- check(objectQuestion, dynamicNone, 'Object? <: T');
- check(objectStar, dynamicNone, 'Object? <: T');
- check(voidNone, objectQuestion, 'Object? <: T');
- check(voidNone, objectStar, 'Object? <: T');
- }
-
- void test_left_null() {
- // Null <: T is trivially satisfied by the constraint Null <: T.
- _checkIsSubtypeMatchOf(nullNone, T_none, [T], ['Null <: T'],
- covariant: false);
-
- // For any other type X, Null <: X is satisfied without the need for any
- // constraints.
- _checkOrdinarySubtypeMatch(nullNone, listQuestion(T_none), [T],
- covariant: false);
- _checkOrdinarySubtypeMatch(nullNone, stringQuestion, [T], covariant: false);
- _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: false);
- _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: false);
- _checkOrdinarySubtypeMatch(nullNone, objectQuestion, [T], covariant: false);
- _checkOrdinarySubtypeMatch(nullNone, nullNone, [T], covariant: false);
- _checkOrdinarySubtypeMatch(
- nullNone,
- functionTypeQuestion(returnType: voidNone),
- [T],
- covariant: false,
- );
- }
-
- void test_right_dynamic() {
- // T <: dynamic is trivially satisfied by the constraint T <: dynamic.
- _checkIsSubtypeMatchOf(T_none, dynamicNone, [T], ['T <: dynamic'],
- covariant: true);
-
- // For any other type X, X <: dynamic is satisfied without the need for any
- // constraints.
- _checkOrdinarySubtypeMatch(listNone(T_none), dynamicNone, [T],
- covariant: true);
- _checkOrdinarySubtypeMatch(stringNone, dynamicNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(voidNone, dynamicNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(dynamicNone, dynamicNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(objectNone, dynamicNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(
- functionTypeNone(
- parameters: [
- requiredParameter(type: intNone),
- ],
- returnType: stringNone,
- ),
- dynamicNone,
- [T],
- covariant: true,
- );
- }
-
- void test_right_object() {
- // T <: Object is trivially satisfied by the constraint T <: Object.
- _checkIsSubtypeMatchOf(T_none, objectNone, [T], ['T <: Object'],
- covariant: true);
-
- // For any other type X, X <: Object is satisfied without the need for any
- // constraints.
- _checkOrdinarySubtypeMatch(listNone(T_none), objectNone, [T],
- covariant: true);
- _checkOrdinarySubtypeMatch(stringNone, objectNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(voidNone, objectNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(dynamicNone, objectNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(objectNone, objectNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(nullNone, objectNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(
- functionTypeNone(
- parameters: [
- requiredParameter(type: intNone),
- ],
- returnType: stringNone,
- ),
- objectNone,
- [T],
- covariant: true,
- );
- }
-
- void test_right_void() {
- // T <: void is trivially satisfied by the constraint T <: void.
- _checkIsSubtypeMatchOf(T_none, voidNone, [T], ['T <: void'],
- covariant: true);
-
- // For any other type X, X <: void is satisfied without the need for any
- // constraints.
- _checkOrdinarySubtypeMatch(listNone(T_none), voidNone, [T],
- covariant: true);
- _checkOrdinarySubtypeMatch(stringNone, voidNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(voidNone, voidNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(dynamicNone, voidNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(objectNone, voidNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: true);
- _checkOrdinarySubtypeMatch(
- functionTypeNone(
- parameters: [
- requiredParameter(type: intNone),
- ],
- returnType: stringNone,
- ),
- voidNone,
- [T],
- covariant: true,
- );
- }
-
- void test_typeParameter_left_covariant() {
- // When doing a covariant match, the type parameters we're trying to find
- // types for are on the left hand side.
- _checkIsSubtypeMatchOf(T_none, stringNone, [T], ['T <: String'],
- covariant: true);
- }
-
- void test_typeParameter_left_covariant_match() {
- // When doing a covariant match, the type parameters we're trying to find
- // types for are on the left hand side. If a type parameter appears on the
- // right hand side, there is a condition in which the constraint can be
- // satisfied: where both parameters appear at corresponding locations in the
- // type tree.
- //
- // In other words, T <: S can be satisfied trivially by the constraint
- // T <: S.
- var S = typeParameter('S');
- var S_none = typeParameterTypeNone(S);
- _checkIsSubtypeMatchOf(T_none, S_none, [T], ['T <: S'], covariant: true);
- }
-
- void test_typeParameter_left_covariant_no_match() {
- // When doing a covariant match, the type parameters we're trying to find
- // types for are on the left hand side. If a type parameter appears on the
- // right hand side, it's probable that the constraint can't be satisfied,
- // because there is no possible type for the LHS (other than bottom)
- // that's guaranteed to satisfy the relation for all possible assignments of
- // the RHS type parameter.
- //
- // In other words, no match can be found for List<T> <: S because regardless
- // of T, we can't guarantee that List<T> <: S for all S.
- var S = typeParameter('S');
- var S_none = typeParameterTypeNone(S);
- _checkIsNotSubtypeMatchOf(listNone(T_none), S_none, [T], covariant: true);
- }
-
- void test_typeParameter_nullable() {
- _checkIsSubtypeMatchOf(T_question, stringQuestion, [T], ['T <: String'],
- covariant: true);
-
- _checkIsSubtypeMatchOf(stringQuestion, T_question, [T], ['String <: T'],
- covariant: false);
- }
-
- void test_typeParameter_right_contravariant() {
- // When doing a contravariant match, the type parameters we're trying to
- // find types for are on the right hand side.
- _checkIsSubtypeMatchOf(stringNone, T_none, [T], ['String <: T'],
- covariant: false);
- }
-
- void test_typeParameter_right_contravariant_direct() {
- // When doing a contravariant match, the type parameters we're trying to
- // find types for are on the right hand side. If a type parameter also
- // appears on the left hand side, there is a condition in which the
- // constraint can be satisfied without consulting the bound of the LHS type
- // parameter: the condition where both parameters appear at corresponding
- // locations in the type tree.
- //
- // In other words, List<S> <: List<T> is satisfied provided that
- // S <: T.
- var S = typeParameter('S');
- var S_none = typeParameterTypeNone(S);
- _checkIsSubtypeMatchOf(listNone(S_none), listNone(T_none), [T], ['S <: T'],
- covariant: false);
- }
-
- void test_typeParameter_right_contravariant_via_bound() {
- // When doing a contravariant match, the type parameters we're trying to
- // find types for are on the right hand side. If a type parameter also
- // appears on the left hand side, we may have to constrain the RHS type
- // parameter using the bounds of the LHS type parameter.
- //
- // In other words, S <: List<T> is satisfied provided that
- // bound(S) <: List<T>.
- var S = typeParameter('S', bound: listNone(stringNone));
- var S_none = typeParameterTypeNone(S);
- _checkIsSubtypeMatchOf(S_none, listNone(T_none), [T], ['String <: T'],
- covariant: false);
- }
-
- void test_variance_contravariant() {
- // class A<in T>
- var T = typeParameter('T', variance: Variance.contravariant);
- var T_none = typeParameterTypeNone(T);
- var A = class_(name: 'A', typeParameters: [T]);
-
- _checkIsSubtypeMatchOf(
- interfaceTypeNone(A, typeArguments: [T_none]),
- interfaceTypeNone(A, typeArguments: [numNone]),
- [T],
- ['num <: in T'],
- covariant: true,
- );
- }
-
- void test_variance_covariant() {
- // class A<out T>
- var T = typeParameter('T', variance: Variance.covariant);
- var T_none = typeParameterTypeNone(T);
- var A = class_(name: 'A', typeParameters: [T]);
-
- _checkIsSubtypeMatchOf(
- interfaceTypeNone(A, typeArguments: [T_none]),
- interfaceTypeNone(A, typeArguments: [numNone]),
- [T],
- ['out T <: num'],
- covariant: true,
- );
- }
-
- void test_variance_invariant() {
- // class A<inout T>
- var T = typeParameter('T', variance: Variance.invariant);
- var T_none = typeParameterTypeNone(T);
- var A = class_(name: 'A', typeParameters: [T]);
-
- _checkIsSubtypeMatchOf(
- interfaceTypeNone(A, typeArguments: [T_none]),
- interfaceTypeNone(A, typeArguments: [numNone]),
- [T],
- ['inout T <: num', 'num <: inout T'],
- covariant: true,
- );
- }
-
- void _checkIsNotSubtypeMatchOf(
- DartType subtype,
- DartType supertype,
- List<TypeParameterElement> typeFormals, {
- @required bool covariant,
- }) {
- var inferrer = GenericInferrer(typeSystem, typeFormals);
-
- var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
- covariant: covariant);
- expect(success, isFalse);
-
- inferrer.constraints.forEach((typeParameter, constraints) {
- expect(constraints, isEmpty);
- });
- }
-
- void _checkIsSubtypeMatchOf(
- DartType subtype,
- DartType supertype,
- List<TypeParameterElement> typeFormals,
- Iterable<String> expectedConstraints, {
- @required bool covariant,
- }) {
- var inferrer = GenericInferrer(typeSystem, typeFormals);
-
- var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
- covariant: covariant);
- expect(success, isTrue);
-
- var formattedConstraints = <String>[];
- inferrer.constraints.forEach((typeParameter, constraints) {
- for (var constraint in constraints) {
- formattedConstraints.add(
- constraint.format(
- typeParameter.getDisplayString(withNullability: true),
- withNullability: true,
- ),
- );
- }
- });
- expect(formattedConstraints, unorderedEquals(expectedConstraints));
- }
-
- void _checkOrdinarySubtypeMatch(
- DartType subtype,
- DartType supertype,
- List<TypeParameterElement> typeFormals, {
- @required bool covariant,
- }) {
- var expectSuccess = typeSystem.isSubtypeOf(subtype, supertype);
- if (expectSuccess) {
- _checkIsSubtypeMatchOf(subtype, supertype, typeFormals, [],
- covariant: covariant);
- } else {
- _checkIsNotSubtypeMatchOf(subtype, supertype, typeFormals,
- covariant: covariant);
- }
- }
-}
-
-@reflectiveTest
class GenericFunctionInferenceTest extends AbstractTypeSystemNullSafetyTest {
void test_boundedByAnotherTypeParameter() {
// <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
@@ -994,7 +393,7 @@
parameters: [
requiredParameter(type: numNone),
],
- returnType: intNone,
+ returnType: intQuestion,
),
),
[numNone],
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 241aff8..e08cff7 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -20,6 +20,7 @@
import 'subtype_test.dart' as subtype;
import 'top_merge_test.dart' as top_merge;
import 'type_algebra_test.dart' as type_algebra;
+import 'type_constraint_gatherer_test.dart' as type_constraint_gatherer;
import 'type_parameter_element_test.dart' as type_parameter_element;
import 'type_visitor_test.dart' as type_visitor;
import 'upper_lower_bound_test.dart' as upper_bound;
@@ -43,6 +44,7 @@
subtype.main();
top_merge.main();
type_algebra.main();
+ type_constraint_gatherer.main();
type_parameter_element.main();
type_visitor.main();
upper_bound.main();
diff --git a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
new file mode 100644
index 0000000..87109c8b
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
@@ -0,0 +1,1118 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_constraint_gatherer.dart';
+import 'package:analyzer/src/dart/element/type_schema.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeConstraintGathererTest);
+ });
+}
+
+@reflectiveTest
+class TypeConstraintGathererTest extends AbstractTypeSystemNullSafetyTest {
+ TypeParameterElement T;
+ TypeParameterType T_none;
+ TypeParameterType T_question;
+ TypeParameterType T_star;
+
+ UnknownInferredType get unknownType => UnknownInferredType.instance;
+
+ @override
+ void setUp() {
+ super.setUp();
+ T = typeParameter('T');
+ T_none = typeParameterTypeNone(T);
+ T_question = typeParameterTypeQuestion(T);
+ T_star = typeParameterTypeStar(T);
+ }
+
+ /// If `P` and `Q` are identical types, then the subtype match holds
+ /// under no constraints.
+ test_equal_left_right() {
+ _checkMatch([T], intNone, intNone, true, ['_ <: T <: _']);
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ requiredParameter(type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ requiredParameter(type: intNone),
+ ],
+ ),
+ true,
+ ['_ <: T <: _'],
+ );
+
+ var T1 = typeParameter('T1');
+ var T2 = typeParameter('T2');
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: typeParameterTypeNone(T1),
+ typeFormals: [T1],
+ ),
+ functionTypeNone(
+ returnType: typeParameterTypeNone(T2),
+ typeFormals: [T2],
+ ),
+ true,
+ ['_ <: T <: _'],
+ );
+ }
+
+ test_functionType_hasTypeFormals() {
+ var T1 = typeParameter('T1');
+ var S1 = typeParameter('S1');
+
+ var T1_none = typeParameterTypeNone(T1);
+ var S1_none = typeParameterTypeNone(S1);
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: T_none,
+ typeFormals: [T1],
+ parameters: [
+ requiredParameter(type: T1_none),
+ ],
+ ),
+ functionTypeNone(
+ returnType: intNone,
+ typeFormals: [S1],
+ parameters: [
+ requiredParameter(type: S1_none),
+ ],
+ ),
+ false,
+ ['_ <: T <: int'],
+ );
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: intNone,
+ typeFormals: [T1],
+ parameters: [
+ requiredParameter(type: T1_none),
+ ],
+ ),
+ functionTypeNone(
+ returnType: T_none,
+ typeFormals: [S1],
+ parameters: [
+ requiredParameter(type: S1_none),
+ ],
+ ),
+ true,
+ ['int <: T <: _'],
+ );
+
+ // We unified type formals, but still not match because return types.
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: intNone,
+ typeFormals: [T1],
+ parameters: [
+ requiredParameter(type: T1_none),
+ ],
+ ),
+ functionTypeNone(
+ returnType: stringNone,
+ typeFormals: [S1],
+ parameters: [
+ requiredParameter(type: S1_none),
+ ],
+ ),
+ false,
+ );
+ }
+
+ test_functionType_hasTypeFormals_bounds_different_subtype() {
+ var T1 = typeParameter('T1', bound: intNone);
+ var S1 = typeParameter('S1', bound: numNone);
+ _checkNotMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1]),
+ false,
+ );
+ }
+
+ test_functionType_hasTypeFormals_bounds_different_top() {
+ var T1 = typeParameter('T1', bound: voidNone);
+ var S1 = typeParameter('S1', bound: dynamicNone);
+ _checkMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1]),
+ false,
+ ['_ <: T <: int'],
+ );
+ }
+
+ test_functionType_hasTypeFormals_bounds_different_unrelated() {
+ var T1 = typeParameter('T1', bound: intNone);
+ var S1 = typeParameter('S1', bound: stringNone);
+ _checkNotMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1]),
+ false,
+ );
+ }
+
+ test_functionType_hasTypeFormals_bounds_same_leftDefault_rightDefault() {
+ var T1 = typeParameter('T1');
+ var S1 = typeParameter('S1');
+ _checkMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1]),
+ false,
+ ['_ <: T <: int'],
+ );
+ }
+
+ test_functionType_hasTypeFormals_bounds_same_leftDefault_rightObjectQ() {
+ var T1 = typeParameter('T1');
+ var S1 = typeParameter('S1', bound: objectQuestion);
+ _checkMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1]),
+ false,
+ ['_ <: T <: int'],
+ );
+ }
+
+ @FailingTest(reason: 'Closure of type constraints is not implemented yet')
+ test_functionType_hasTypeFormals_closure() {
+ var T = typeParameter('T');
+ var X = typeParameter('X');
+ var Y = typeParameter('Y');
+
+ var T_none = typeParameterTypeNone(T);
+ var X_none = typeParameterTypeNone(X);
+ var Y_none = typeParameterTypeNone(Y);
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ typeFormals: [X],
+ returnType: T_none,
+ parameters: [
+ requiredParameter(type: X_none),
+ ],
+ ),
+ functionTypeNone(
+ typeFormals: [Y],
+ returnType: listNone(Y_none),
+ parameters: [
+ requiredParameter(type: Y_none),
+ ],
+ ),
+ true,
+ ['_ <: T <: List<Object?>'],
+ );
+ }
+
+ test_functionType_hasTypeFormals_differentCount() {
+ var T1 = typeParameter('T1');
+ var S1 = typeParameter('S1');
+ var S2 = typeParameter('S2');
+ _checkNotMatch(
+ [T],
+ functionTypeNone(returnType: T_none, typeFormals: [T1]),
+ functionTypeNone(returnType: intNone, typeFormals: [S1, S2]),
+ false,
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_extraOptionalLeft() {
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ positionalParameter(type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [],
+ ),
+ true,
+ ['_ <: T <: _'],
+ );
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [],
+ ),
+ true,
+ ['_ <: T <: _'],
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_extraRequiredLeft() {
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ requiredParameter(type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [],
+ ),
+ true,
+ );
+
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedRequiredParameter(name: 'a', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [],
+ ),
+ true,
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_extraRight() {
+ _checkNotMatch(
+ [T],
+ functionTypeNone(returnType: voidNone),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ requiredParameter(type: T_none),
+ ],
+ ),
+ true,
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_leftOptionalNamed() {
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: T_none),
+ ],
+ ),
+ true,
+ ['_ <: T <: int'],
+ );
+
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: T_none),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ ],
+ ),
+ false,
+ ['int <: T <: _'],
+ );
+
+ // int vs. String
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: stringNone),
+ ],
+ ),
+ true,
+ );
+
+ // Skip left non-required named.
+ _checkMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ namedParameter(name: 'b', type: intNone),
+ namedParameter(name: 'c', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'b', type: T_none),
+ ],
+ ),
+ true,
+ ['_ <: T <: int'],
+ );
+
+ // Not match if skip left required named.
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedRequiredParameter(name: 'a', type: intNone),
+ namedParameter(name: 'b', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'b', type: T_none),
+ ],
+ ),
+ true,
+ );
+
+ // Not match if skip right named.
+ _checkNotMatch(
+ [T],
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'b', type: intNone),
+ ],
+ ),
+ functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ namedParameter(name: 'a', type: intNone),
+ namedParameter(name: 'b', type: T_none),
+ ],
+ ),
+ true,
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_leftOptionalPositional() {
+ void check({
+ @required DartType left,
+ @required ParameterElement right,
+ @required bool leftSchema,
+ @required String expected,
+ }) {
+ var P = functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ positionalParameter(type: left),
+ ],
+ );
+ var Q = functionTypeNone(
+ returnType: voidNone,
+ parameters: [right],
+ );
+
+ if (expected != null) {
+ _checkMatch([T], P, Q, leftSchema, [expected]);
+ } else {
+ _checkNotMatch([T], P, Q, leftSchema);
+ }
+ }
+
+ check(
+ left: intNone,
+ right: requiredParameter(type: T_none),
+ leftSchema: true,
+ expected: '_ <: T <: int',
+ );
+ check(
+ left: T_none,
+ right: requiredParameter(type: intNone),
+ leftSchema: false,
+ expected: 'int <: T <: _',
+ );
+
+ check(
+ left: intNone,
+ right: positionalParameter(type: T_none),
+ leftSchema: true,
+ expected: '_ <: T <: int',
+ );
+ check(
+ left: T_none,
+ right: positionalParameter(type: intNone),
+ leftSchema: false,
+ expected: 'int <: T <: _',
+ );
+
+ check(
+ left: intNone,
+ right: requiredParameter(type: stringNone),
+ leftSchema: true,
+ expected: null,
+ );
+ check(
+ left: intNone,
+ right: positionalParameter(type: stringNone),
+ leftSchema: true,
+ expected: null,
+ );
+
+ check(
+ left: intNone,
+ right: namedParameter(type: intNone, name: 'a'),
+ leftSchema: true,
+ expected: null,
+ );
+ check(
+ left: intNone,
+ right: namedParameter(type: intNone, name: 'a'),
+ leftSchema: false,
+ expected: null,
+ );
+ }
+
+ test_functionType_noTypeFormals_parameters_leftRequiredPositional() {
+ void check({
+ @required DartType left,
+ @required ParameterElement right,
+ @required bool leftSchema,
+ @required String expected,
+ }) {
+ var P = functionTypeNone(
+ returnType: voidNone,
+ parameters: [
+ requiredParameter(type: left),
+ ],
+ );
+ var Q = functionTypeNone(
+ returnType: voidNone,
+ parameters: [right],
+ );
+
+ if (expected != null) {
+ _checkMatch([T], P, Q, leftSchema, [expected]);
+ } else {
+ _checkNotMatch([T], P, Q, leftSchema);
+ }
+ }
+
+ check(
+ left: intNone,
+ right: requiredParameter(type: T_none),
+ leftSchema: true,
+ expected: '_ <: T <: int',
+ );
+ check(
+ left: T_none,
+ right: requiredParameter(type: intNone),
+ leftSchema: false,
+ expected: 'int <: T <: _',
+ );
+
+ check(
+ left: intNone,
+ right: requiredParameter(type: stringNone),
+ leftSchema: true,
+ expected: null,
+ );
+
+ check(
+ left: intNone,
+ right: positionalParameter(type: T_none),
+ leftSchema: true,
+ expected: null,
+ );
+
+ check(
+ left: intNone,
+ right: namedParameter(type: T_none, name: 'a'),
+ leftSchema: true,
+ expected: null,
+ );
+ }
+
+ test_functionType_noTypeFormals_returnType() {
+ _checkMatch(
+ [T],
+ functionTypeNone(returnType: T_none),
+ functionTypeNone(returnType: intNone),
+ false,
+ ['_ <: T <: int'],
+ );
+
+ _checkNotMatch(
+ [T],
+ functionTypeNone(returnType: stringNone),
+ functionTypeNone(returnType: intNone),
+ false,
+ );
+ }
+
+ /// If `P` is `C<M0, ..., Mk> and `Q` is `C<N0, ..., Nk>`, then the match
+ /// holds under constraints `C0 + ... + Ck`:
+ /// If `Mi` is a subtype match for `Ni` with respect to L under
+ /// constraints `Ci`.
+ test_interfaceType_same() {
+ _checkMatch(
+ [T],
+ listNone(T_none),
+ listNone(numNone),
+ false,
+ ['_ <: T <: num'],
+ );
+ _checkMatch(
+ [T],
+ listNone(intNone),
+ listNone(T_none),
+ true,
+ ['int <: T <: _'],
+ );
+
+ _checkNotMatch([T], listNone(intNone), listNone(stringNone), false);
+
+ _checkMatch(
+ [T],
+ mapNone(intNone, listNone(T_none)),
+ mapNone(numNone, listNone(stringNone)),
+ false,
+ ['_ <: T <: String'],
+ );
+ _checkMatch(
+ [T],
+ mapNone(intNone, listNone(stringNone)),
+ mapNone(numNone, listNone(T_none)),
+ true,
+ ['String <: T <: _'],
+ );
+
+ _checkNotMatch(
+ [T],
+ mapNone(T_none, listNone(intNone)),
+ mapNone(numNone, listNone(stringNone)),
+ false,
+ );
+ }
+
+ /// If `P` is `C0<M0, ..., Mk>` and `Q` is `C1<N0, ..., Nj>` then the match
+ /// holds with respect to `L` under constraints `C`:
+ /// If `C1<B0, ..., Bj>` is a superinterface of `C0<M0, ..., Mk>` and
+ /// `C1<B0, ..., Bj>` is a subtype match for `C1<N0, ..., Nj>` with
+ /// respect to `L` under constraints `C`.
+ test_interfaceType_superInterface() {
+ _checkMatch(
+ [T],
+ listNone(T_none),
+ iterableNone(numNone),
+ false,
+ ['_ <: T <: num'],
+ );
+ _checkMatch(
+ [T],
+ listNone(intNone),
+ iterableNone(T_none),
+ true,
+ ['int <: T <: _'],
+ );
+ _checkMatch(
+ [T],
+ listNone(intNone),
+ iterableStar(T_none),
+ true,
+ ['int <: T <: _'],
+ );
+
+ _checkNotMatch([T], listNone(intNone), iterableNone(stringNone), true);
+ }
+
+ void test_interfaceType_topMerge() {
+ var testClassIndex = 0;
+
+ void check1(
+ DartType extendsTypeArgument,
+ DartType implementsTypeArgument,
+ String expectedConstraint,
+ ) {
+ var library = library_(
+ uriStr: 'package:test/test.dart',
+ analysisSession: analysisContext.analysisSession,
+ typeSystem: typeSystem,
+ );
+
+ // class A<T> {}
+ var A = class_(name: 'A', typeParameters: [
+ typeParameter('T'),
+ ]);
+ A.enclosingElement = library.definingCompilationUnit;
+
+ // class B<T> extends A<T> {}
+ var B_T = typeParameter('T');
+ var B_T_none = typeParameterTypeNone(B_T);
+ var B = class_(
+ name: 'B',
+ typeParameters: [B_T],
+ superType: interfaceTypeNone(A, typeArguments: [B_T_none]),
+ );
+ B.enclosingElement = library.definingCompilationUnit;
+
+ // class Cx extends A<> implements B<> {}
+ var C = class_(
+ name: 'C${testClassIndex++}',
+ superType: interfaceTypeNone(
+ A,
+ typeArguments: [extendsTypeArgument],
+ ),
+ interfaces: [
+ interfaceTypeNone(
+ B,
+ typeArguments: [implementsTypeArgument],
+ )
+ ],
+ );
+ C.enclosingElement = library.definingCompilationUnit;
+
+ _checkMatch(
+ [T],
+ interfaceTypeNone(C),
+ interfaceTypeNone(A, typeArguments: [T_none]),
+ true,
+ [expectedConstraint],
+ );
+ }
+
+ void check(
+ DartType typeArgument1,
+ DartType typeArgument2,
+ String expectedConstraint,
+ ) {
+ check1(typeArgument1, typeArgument2, expectedConstraint);
+ check1(typeArgument2, typeArgument1, expectedConstraint);
+ }
+
+ check(objectQuestion, dynamicNone, 'Object? <: T <: _');
+ check(objectStar, dynamicNone, 'Object? <: T <: _');
+ check(voidNone, objectQuestion, 'Object? <: T <: _');
+ check(voidNone, objectStar, 'Object? <: T <: _');
+ }
+
+ /// If `P` is `FutureOr<P0>` the match holds under constraint set `C1 + C2`:
+ /// If `Future<P0>` is a subtype match for `Q` under constraint set `C1`.
+ /// And if `P0` is a subtype match for `Q` under constraint set `C2`.
+ test_left_futureOr() {
+ _checkMatch(
+ [T],
+ futureOrNone(T_none),
+ futureOrNone(intNone),
+ false,
+ ['_ <: T <: int'],
+ );
+
+ // This is 'T <: int' and 'T <: Future<int>'.
+ _checkMatch(
+ [T],
+ futureOrNone(T_none),
+ futureNone(intNone),
+ false,
+ ['_ <: T <: Never'],
+ );
+
+ _checkNotMatch([T], futureOrNone(T_none), intNone, false);
+ }
+
+ /// If `P` is `Never` then the match holds under no constraints.
+ test_left_never() {
+ _checkMatch([T], neverNone, intNone, false, ['_ <: T <: _']);
+ }
+
+ /// If `P` is `Null`, then the match holds under no constraints:
+ /// Only if `Q` is nullable.
+ test_left_null() {
+ _checkNotMatch([T], nullNone, intNone, true);
+
+ _checkMatch(
+ [T],
+ nullNone,
+ T_none,
+ true,
+ ['Null <: T <: _'],
+ );
+
+ _checkMatch(
+ [T],
+ nullNone,
+ futureOrNone(T_none),
+ true,
+ ['Null <: T <: _'],
+ );
+
+ void matchNoConstraints(DartType Q) {
+ _checkMatch(
+ [T],
+ nullNone,
+ Q,
+ true,
+ ['_ <: T <: _'],
+ );
+ }
+
+ matchNoConstraints(listQuestion(T_none));
+ matchNoConstraints(stringQuestion);
+ matchNoConstraints(voidNone);
+ matchNoConstraints(dynamicNone);
+ matchNoConstraints(objectQuestion);
+ matchNoConstraints(nullNone);
+ matchNoConstraints(
+ functionTypeQuestion(returnType: voidNone),
+ );
+ }
+
+ /// If `P` is `P0?` the match holds under constraint set `C1 + C2`:
+ /// If `P0` is a subtype match for `Q` under constraint set `C1`.
+ /// And if `Null` is a subtype match for `Q` under constraint set `C2`.
+ test_left_suffixQuestion() {
+ // TODO(scheglov) any better test case?
+ _checkMatch(
+ [T],
+ numQuestion,
+ dynamicNone,
+ true,
+ ['_ <: T <: _'],
+ );
+
+ _checkNotMatch([T], T_question, intNone, true);
+ }
+
+ /// If `P` is a legacy type `P0*` then the match holds under constraint
+ /// set `C`:
+ /// Only if `P0` is a subtype match for `Q` under constraint set `C`.
+ test_left_suffixStar() {
+ _checkMatch([T], T_star, numNone, false, ['_ <: T <: num']);
+ _checkMatch([T], T_star, numQuestion, false, ['_ <: T <: num?']);
+ _checkMatch([T], T_star, numStar, false, ['_ <: T <: num*']);
+
+ _checkMatch([T], numStar, T_none, true, ['num* <: T <: _']);
+ _checkMatch([T], numStar, T_question, true, ['num <: T <: _']);
+ _checkMatch([T], numStar, T_star, true, ['num <: T <: _']);
+ }
+
+ /// If `P` is a type variable `X` in `L`, then the match holds:
+ /// Under constraint `_ <: X <: Q`.
+ test_left_typeParameter() {
+ void checkMatch(DartType right, String expected) {
+ _checkMatch([T], T_none, right, false, [expected]);
+ }
+
+ checkMatch(numNone, '_ <: T <: num');
+ checkMatch(numQuestion, '_ <: T <: num?');
+ checkMatch(numStar, '_ <: T <: num*');
+ }
+
+ /// If `P` is a type variable `X` with bound `B` (or a promoted type
+ /// variable `X & B`), the match holds with constraint set `C`:
+ /// If `B` is a subtype match for `Q` with constraint set `C`.
+ /// Note: we have already eliminated the case that `X` is a variable in `L`.
+ test_left_typeParameterOther() {
+ _checkMatch(
+ [T],
+ typeParameterTypeNone(
+ typeParameter('U', bound: intNone),
+ ),
+ numNone,
+ false,
+ ['_ <: T <: _'],
+ );
+
+ _checkMatch(
+ [T],
+ promotedTypeParameterTypeNone(
+ typeParameter('U'),
+ intNone,
+ ),
+ numNone,
+ false,
+ ['_ <: T <: _'],
+ );
+
+ _checkNotMatch(
+ [T],
+ typeParameterTypeNone(
+ typeParameter('U'),
+ ),
+ numNone,
+ false,
+ );
+ }
+
+ /// If `P` is `_` then the match holds with no constraints.
+ test_left_unknown() {
+ _checkMatch([T], unknownType, numNone, true, ['_ <: T <: _']);
+ }
+
+ test_right_functionClass() {
+ _checkMatch(
+ [T],
+ functionTypeNone(returnType: voidNone),
+ functionNone,
+ true,
+ ['_ <: T <: _'],
+ );
+ }
+
+ /// If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
+ test_right_futureOr() {
+ // If `P` is `FutureOr<P0>` and `P0` is a subtype match for `Q0` under
+ // constraint set `C`.
+ _checkMatch(
+ [T],
+ futureOrNone(T_none),
+ futureOrNone(numNone),
+ false,
+ ['_ <: T <: num'],
+ );
+ _checkMatch(
+ [T],
+ futureOrNone(numNone),
+ futureOrNone(T_none),
+ true,
+ ['num <: T <: _'],
+ );
+ _checkNotMatch(
+ [T],
+ futureOrNone(stringNone),
+ futureOrNone(intNone),
+ true,
+ );
+
+ // Or if `P` is a subtype match for `Future<Q0>` under non-empty
+ // constraint set `C`.
+ _checkMatch(
+ [T],
+ futureNone(T_none),
+ futureOrNone(numNone),
+ false,
+ ['_ <: T <: num'],
+ );
+ _checkMatch(
+ [T],
+ futureNone(intNone),
+ futureOrNone(T_none),
+ true,
+ ['int <: T <: _'],
+ );
+ _checkMatch(
+ [T],
+ futureNone(intNone),
+ futureOrNone(objectNone),
+ true,
+ ['_ <: T <: _'],
+ );
+ _checkNotMatch(
+ [T],
+ futureNone(stringNone),
+ futureOrNone(intNone),
+ true,
+ );
+
+ // Or if `P` is a subtype match for `Q0` under constraint set `C`.
+ _checkMatch(
+ [T],
+ listNone(T_none),
+ futureOrNone(listNone(intNone)),
+ false,
+ ['_ <: T <: int'],
+ );
+ _checkMatch(
+ [T],
+ neverNone,
+ futureOrNone(T_none),
+ true,
+ ['Never <: T <: _'],
+ );
+
+ // Or if `P` is a subtype match for `Future<Q0>` under empty
+ // constraint set `C`.
+ _checkMatch(
+ [T],
+ futureNone(intNone),
+ futureOrNone(numNone),
+ false,
+ ['_ <: T <: _'],
+ );
+
+ // Otherwise.
+ _checkNotMatch(
+ [T],
+ listNone(T_none),
+ futureOrNone(intNone),
+ false,
+ );
+ }
+
+ /// If `Q` is `Object`, then the match holds under no constraints:
+ /// Only if `P` is non-nullable.
+ test_right_object() {
+ _checkMatch([T], intNone, objectNone, false, ['_ <: T <: _']);
+ _checkNotMatch([T], intQuestion, objectNone, false);
+
+ _checkNotMatch([T], dynamicNone, objectNone, false);
+
+ {
+ var U = typeParameter('U', bound: numQuestion);
+ _checkNotMatch([T], typeParameterTypeNone(U), objectNone, false);
+ }
+ }
+
+ /// If `Q` is `Q0?` the match holds under constraint set `C`:
+ test_right_suffixQuestion() {
+ // If `P` is `P0?` and `P0` is a subtype match for `Q0` under
+ // constraint set `C`.
+ _checkMatch([T], T_question, numQuestion, false, ['_ <: T <: num']);
+ _checkMatch([T], intQuestion, T_question, true, ['int <: T <: _']);
+
+ // Or if `P` is a subtype match for `Q0` under non-empty
+ // constraint set `C`.
+ _checkMatch(
+ [T],
+ intNone,
+ T_question,
+ false,
+ ['int <: T <: _'],
+ );
+
+ // Or if `P` is a subtype match for `Null` under constraint set `C`.
+ _checkMatch([T], nullNone, intQuestion, true, ['_ <: T <: _']);
+
+ // Or if `P` is a subtype match for `Q0` under empty
+ // constraint set `C`.
+ _checkMatch([T], intNone, intQuestion, true, ['_ <: T <: _']);
+
+ _checkNotMatch([T], intNone, stringQuestion, true);
+ _checkNotMatch([T], intQuestion, stringQuestion, true);
+ _checkNotMatch([T], intStar, stringQuestion, true);
+ }
+
+ /// If `Q` is a legacy type `Q0*` then the match holds under constraint
+ /// set `C`:
+ /// Only if `P` is a subtype match for `Q?` under constraint set `C`.
+ test_right_suffixStar() {
+ _checkMatch([T], T_none, numStar, false, ['_ <: T <: num*']);
+ _checkMatch([T], T_star, numStar, false, ['_ <: T <: num*']);
+ _checkMatch([T], T_question, numStar, false, ['_ <: T <: num']);
+
+ _checkMatch([T], numNone, T_star, true, ['num <: T <: _']);
+ _checkMatch([T], numQuestion, T_star, true, ['num <: T <: _']);
+ _checkMatch([T], numStar, T_star, true, ['num <: T <: _']);
+ }
+
+ /// If `Q` is `dynamic`, `Object?`, or `void` then the match holds under
+ /// no constraints.
+ test_right_top() {
+ _checkMatch([T], intNone, dynamicNone, false, ['_ <: T <: _']);
+ _checkMatch([T], intNone, objectQuestion, false, ['_ <: T <: _']);
+ _checkMatch([T], intNone, voidNone, false, ['_ <: T <: _']);
+ }
+
+ /// If `Q` is a type variable `X` in `L`, then the match holds:
+ /// Under constraint `P <: X <: _`.
+ test_right_typeParameter() {
+ void checkMatch(DartType left, String expected) {
+ _checkMatch([T], left, T_none, true, [expected]);
+ }
+
+ checkMatch(numNone, 'num <: T <: _');
+ checkMatch(numQuestion, 'num? <: T <: _');
+ checkMatch(numStar, 'num* <: T <: _');
+ }
+
+ /// If `Q` is `_` then the match holds with no constraints.
+ test_right_unknown() {
+ _checkMatch([T], numNone, unknownType, true, ['_ <: T <: _']);
+ _checkMatch([T], numNone, unknownType, true, ['_ <: T <: _']);
+ }
+
+ void _checkMatch(
+ List<TypeParameterElement> typeParameters,
+ DartType P,
+ DartType Q,
+ bool leftSchema,
+ List<String> expected,
+ ) {
+ var gatherer = TypeConstraintGatherer(
+ typeSystem: typeSystem,
+ typeParameters: typeParameters,
+ );
+
+ var isMatch = gatherer.trySubtypeMatch(P, Q, leftSchema);
+ expect(isMatch, isTrue);
+
+ var constraints = gatherer.computeConstraints();
+ var constraintsStr = constraints.entries.map((e) {
+ var lowerStr = e.value.lower.getDisplayString(withNullability: true);
+ var upperStr = e.value.upper.getDisplayString(withNullability: true);
+ return '$lowerStr <: ${e.key.name} <: $upperStr';
+ }).toList();
+
+ expect(constraintsStr, unorderedEquals(expected));
+ }
+
+ void _checkNotMatch(
+ List<TypeParameterElement> typeParameters,
+ DartType P,
+ DartType Q,
+ bool leftSchema,
+ ) {
+ var gatherer = TypeConstraintGatherer(
+ typeSystem: typeSystem,
+ typeParameters: typeParameters,
+ );
+
+ var isMatch = gatherer.trySubtypeMatch(P, Q, leftSchema);
+ expect(isMatch, isFalse);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
index 8e35b70..8503999 100644
--- a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
@@ -38,6 +38,8 @@
/// Override this to change the analysis options for a given set of tests.
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl();
+ bool get enableIndex => false;
+
@override
Future<ResolvedUnitResult> resolveFile(String path) async {
return await driver.getResult(path);
@@ -77,6 +79,7 @@
ResourceUriResolver(resourceProvider)
]),
analysisOptions,
+ enableIndex: enableIndex,
packages: Packages.empty);
scheduler.start();
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index b4e5dff..cf358a3 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -38,4 +38,18 @@
expect(findElement.field('bbb').isConstantEvaluated, isTrue);
expect(findElement.field('values').isConstantEvaluated, isTrue);
}
+
+ test_isEnumConstant() async {
+ await assertNoErrorsInCode(r'''
+enum E {
+ a, b
+}
+''');
+
+ expect(findElement.field('a').isEnumConstant, isTrue);
+ expect(findElement.field('b').isEnumConstant, isTrue);
+
+ expect(findElement.field('index').isEnumConstant, isFalse);
+ expect(findElement.field('values').isEnumConstant, isFalse);
+ }
}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index d51062a..5091559 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -46,15 +46,15 @@
53, 5),
]);
- // TODO(brianwilkerson) Test this more carefully after we can re-write the
- // AST to reflect the expected structure.
-// var creation = findNode.instanceCreation('Foo.bar<int>');
-// assertInstanceCreation(
-// creation,
-// findElement.class_('Foo'),
-// 'Foo',
-// constructorName: 'bar',
-// );
+ var creation = findNode.instanceCreation('Foo.bar<int>');
+ assertInstanceCreation(
+ creation,
+ findElement.class_('Foo'),
+ 'Foo<dynamic>',
+ constructorName: 'bar',
+ expectedConstructorMember: true,
+ expectedSubstitution: {'X': 'dynamic'},
+ );
}
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew_prefix() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 2e7b45c..b975ed7 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -1040,10 +1040,8 @@
abstract class X extends A with U1, U2, M {}
''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 121, 2),
error(CompileTimeErrorCode.MIXIN_OF_NON_CLASS, 121, 2),
error(CompileTimeErrorCode.MIXIN_OF_NON_CLASS, 125, 2),
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 125, 2),
error(
CompileTimeErrorCode
.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index b052e2e..cf03581 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -726,7 +726,7 @@
} else if (node is IndexExpression) {
return node.staticElement;
} else if (node is InstanceCreationExpression) {
- return node.staticElement;
+ return node.constructorName.staticElement;
} else if (node is MethodInvocation) {
return node.methodName.staticElement;
} else if (node is PostfixExpression) {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
index ed3d0fb..d6f56d9 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_name_test.dart
@@ -232,7 +232,7 @@
new A();
}
''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 15, 1),
+ error(StaticWarningCode.NEW_WITH_NON_TYPE, 15, 1),
]);
assertTypeName(
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
index 7ba0920..f2493f1 100644
--- a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
@@ -283,20 +283,6 @@
]);
}
- test_instanceCreation_defaultConstructor() async {
- await assertErrorsInCode(r'''
-class A {
- @deprecated
- A(int i) {}
-}
-f() {
- return new A(1);
-}
-''', [
- error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 55, 8),
- ]);
- }
-
test_instanceCreation_namedConstructor() async {
await assertErrorsInCode(r'''
class A {
@@ -307,7 +293,21 @@
return new A.named(1);
}
''', [
- error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 61, 14),
+ error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 65, 7),
+ ]);
+ }
+
+ test_instanceCreation_unnamedConstructor() async {
+ await assertErrorsInCode(r'''
+class A {
+ @deprecated
+ A(int i) {}
+}
+f() {
+ return new A(1);
+}
+''', [
+ error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 59, 1),
]);
}
@@ -449,20 +449,6 @@
]);
}
- test_superConstructor_defaultConstructor() async {
- await assertErrorsInCode(r'''
-class A {
- @deprecated
- A() {}
-}
-class B extends A {
- B() : super() {}
-}
-''', [
- error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 63, 7),
- ]);
- }
-
test_superConstructor_namedConstructor() async {
await assertErrorsInCode(r'''
class A {
@@ -476,6 +462,20 @@
error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 69, 13),
]);
}
+
+ test_superConstructor_unnamedConstructor() async {
+ await assertErrorsInCode(r'''
+class A {
+ @deprecated
+ A() {}
+}
+class B extends A {
+ B() : super() {}
+}
+''', [
+ error(HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE, 63, 7),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/new_with_non_type_test.dart b/pkg/analyzer/test/src/diagnostics/new_with_non_type_test.dart
index fa26b8c..758cb1f 100644
--- a/pkg/analyzer/test/src/diagnostics/new_with_non_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/new_with_non_type_test.dart
@@ -15,6 +15,18 @@
@reflectiveTest
class NewWithNonTypeTest extends DriverResolutionTest {
+ test_functionTypeAlias() async {
+ await assertErrorsInCode('''
+typedef F = void Function();
+
+void foo() {
+ new F();
+}
+''', [
+ error(StaticWarningCode.NEW_WITH_NON_TYPE, 49, 1),
+ ]);
+ }
+
test_imported() async {
newFile("/test/lib/lib.dart", content: "class B {}");
await assertErrorsInCode('''
@@ -38,4 +50,14 @@
error(StaticWarningCode.NEW_WITH_NON_TYPE, 28, 1),
]);
}
+
+ test_typeParameter() async {
+ await assertErrorsInCode('''
+void foo<T>() {
+ new T();
+}
+''', [
+ error(StaticWarningCode.NEW_WITH_NON_TYPE, 22, 1),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
index 3893cf2..b72081b 100644
--- a/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_null_opt_out_test.dart
@@ -425,7 +425,7 @@
assertType(instanceCreation, 'A*');
_assertLegacyMember(
- instanceCreation.staticElement,
+ instanceCreation.constructorName.staticElement,
_import_a.unnamedConstructor('A'),
);
}
@@ -448,7 +448,7 @@
assertType(instanceCreation, 'A<int*>*');
_assertLegacyMember(
- instanceCreation.staticElement,
+ instanceCreation.constructorName.staticElement,
_import_a.unnamedConstructor('A'),
expectedSubstitution: {'T': 'int*'},
);
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
index 1a2b49b..2842fc2 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
@@ -22,7 +22,7 @@
return const A();
}
''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 21, 1),
+ error(CompileTimeErrorCode.CONST_WITH_NON_TYPE, 21, 1),
]);
}
@@ -40,7 +40,7 @@
await assertErrorsInCode('''
f() { new C(); }
''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 10, 1),
+ error(StaticWarningCode.NEW_WITH_NON_TYPE, 10, 1),
]);
}
diff --git a/pkg/analyzer_cli/LICENSE b/pkg/analyzer_cli/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/analyzer_cli/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2013, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/analyzer_cli/README.md b/pkg/analyzer_cli/README.md
index 03de8b9..a06b656 100644
--- a/pkg/analyzer_cli/README.md
+++ b/pkg/analyzer_cli/README.md
@@ -24,7 +24,6 @@
Specify the path to the package resolution configuration file.
For more information see
[Package Resolution Configuration File](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md).
- This option cannot be used with `--package-root`.
* `--package-warnings`
@@ -78,10 +77,3 @@
* `--url-mapping=libraryUri,/path/to/library.dart`
Use the specified library as the source for that particular import.
-
-The following options are deprecated:
-
-* `--package-root=`<br>
- **Deprecated.** Specify the directory to search for any libraries that are
- imported using `package:`. _This option is replaced as of Dart 1.12 with
- `--packages`._
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 42342cf..3cd2c60 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -598,9 +598,6 @@
} catch (e) {
printAndFail('Unable to read package config data from $path: $e');
}
- } else if (options.packageRootPath != null) {
- var path = normalizePath(options.packageRootPath);
- packageMap = _PackageRootPackageMapBuilder.buildPackageMap(path);
} else {
var cwd = resourceProvider.getResource(path.current);
// Look for .packages.
@@ -679,7 +676,6 @@
CommandLineOptions previous, CommandLineOptions newOptions) {
return previous != null &&
newOptions != null &&
- newOptions.packageRootPath == previous.packageRootPath &&
newOptions.packageConfigPath == previous.packageConfigPath &&
_equalMaps(newOptions.definedVariables, previous.definedVariables) &&
newOptions.log == previous.log &&
@@ -735,28 +731,3 @@
_PackageInfo(this.packages, this.packageMap);
}
-
-class _PackageRootPackageMapBuilder {
- /// In the case that the analyzer is invoked with a --package-root option, we
- /// need to manually create the mapping from package name to folder.
- ///
- /// Given [packageRootPath], creates a simple mapping from package name
- /// to full path on disk (resolving any symbolic links).
- static Map<String, List<Folder>> buildPackageMap(String packageRootPath) {
- var packageRoot = io.Directory(packageRootPath);
- if (!packageRoot.existsSync()) {
- throw _DriverError(
- 'Package root directory ($packageRootPath) does not exist.');
- }
- var packages = packageRoot.listSync(followLinks: false);
- var result = <String, List<Folder>>{};
- for (var package in packages) {
- var packageName = path.basename(package.path);
- var realPath = package.resolveSymbolicLinksSync();
- result[packageName] = [
- PhysicalResourceProvider.INSTANCE.getFolder(realPath)
- ];
- }
- return result;
- }
-}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 2d60cd0..90deb09 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -203,10 +203,6 @@
/// The path to a `.packages` configuration file
String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath;
- /// The path to the package root
- String get packageRootPath =>
- contextBuilderOptions.defaultPackagesDirectoryPath;
-
/// The source files to analyze
List<String> get sourceFiles => _sourceFiles;
@@ -246,18 +242,9 @@
}
}
- // Check package config.
- {
- if (options.packageRootPath != null &&
- options.packageConfigPath != null) {
- printAndFail("Cannot specify both '--package-root' and '--packages.");
- return null; // Only reachable in testing.
- }
- }
-
// Build mode.
if (options.buildModePersistentWorker && !options.buildMode) {
- printAndFail('The option --persisten_worker can be used only '
+ printAndFail('The option --persistent_worker can be used only '
'together with --build-mode.');
return null; // Only reachable in testing.
}
diff --git a/pkg/analyzer_cli/lib/src/perf_report.dart b/pkg/analyzer_cli/lib/src/perf_report.dart
index 4c6aa87..95c1efc 100644
--- a/pkg/analyzer_cli/lib/src/perf_report.dart
+++ b/pkg/analyzer_cli/lib/src/perf_report.dart
@@ -43,7 +43,6 @@
'showPackageWarningsPrefix': options.showPackageWarningsPrefix,
'showSdkWarnings': options.showSdkWarnings,
'definedVariables': options.definedVariables,
- 'packageRootPath': options.packageRootPath,
'packageConfigPath': options.packageConfigPath,
'sourceFiles': options.sourceFiles,
};
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 8e5ce94..9c3b28f 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -59,7 +59,6 @@
expect(options.ignoreUnrecognizedFlags, isFalse);
expect(options.log, isFalse);
expect(options.machineFormat, isFalse);
- expect(options.packageRootPath, isNull);
expect(options.batchMode, isFalse);
expect(options.showPackageWarnings, isFalse);
expect(options.showSdkWarnings, isFalse);
@@ -188,12 +187,6 @@
expect(options.lints, isTrue);
});
- test('package root', () {
- var options = CommandLineOptions.parse(
- ['--dart-sdk', '.', '--package-root', 'bar', 'foo.dart']);
- expect(options.packageRootPath, equals('bar'));
- });
-
test('package warnings', () {
var options = CommandLineOptions.parse(
['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
@@ -238,15 +231,6 @@
expect(options.lintsAreFatal, isTrue);
});
- test("can't specify package and package-root", () {
- var failureMessage;
- CommandLineOptions.parse(
- ['--package-root', '.', '--packages', '.', 'foo.dart'],
- printAndFail: (msg) => failureMessage = msg);
- expect(failureMessage,
- equals("Cannot specify both '--package-root' and '--packages."));
- });
-
test('bad SDK dir', () {
var failureMessage;
CommandLineOptions.parse(['--dart-sdk', '&&&&&', 'foo.dart'],
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 69beb48..49bd399 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -173,6 +173,7 @@
void writeConstructorDeclaration(String className,
{ArgumentList argumentList,
void Function() bodyWriter,
+ String classNameGroupName,
SimpleIdentifier constructorName,
String constructorNameGroupName,
List<String> fieldNames,
@@ -183,7 +184,11 @@
write(Keyword.CONST.lexeme);
write(' ');
}
- write(className);
+ if (classNameGroupName == null) {
+ write(className);
+ } else {
+ addSimpleLinkedEdit(classNameGroupName, className);
+ }
if (constructorName != null) {
write('.');
if (constructorNameGroupName == null) {
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 645201d..15ba518 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -82,6 +82,7 @@
void writeConstructorDeclaration(String className,
{ArgumentList argumentList,
void Function() bodyWriter,
+ String classNameGroupName,
SimpleIdentifier constructorName,
String constructorNameGroupName,
List<String> fieldNames,
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 41ab31e..563d438 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -98,8 +98,8 @@
static const String serverMode = '--server-mode';
- static const String nullSafety = '--sound-null-safety';
- static const String noNullSafety = '--no-sound-null-safety';
+ static const String soundNullSafety = '--sound-null-safety';
+ static const String noSoundNullSafety = '--no-sound-null-safety';
static const String newDeferredSplit = '--new-deferred-split';
static const String reportInvalidInferredDeferredTypes =
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 37094a9..7f4564c 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -461,8 +461,8 @@
new OptionHandler(Flags.noLegacyJavaScript, passThrough),
new OptionHandler(Flags.benchmarkingProduction, passThrough),
new OptionHandler(Flags.benchmarkingExperiment, passThrough),
- new OptionHandler(Flags.nullSafety, setNullSafetyMode),
- new OptionHandler(Flags.noNullSafety, setNullSafetyMode),
+ new OptionHandler(Flags.soundNullSafety, setNullSafetyMode),
+ new OptionHandler(Flags.noSoundNullSafety, setNullSafetyMode),
// TODO(floitsch): remove conditional directives flag.
// We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index aec72f0..6b4bde7 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -16,6 +16,7 @@
import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
import '../../compiler_new.dart' as api;
+import '../commandline_options.dart' show Flags;
import '../common/tasks.dart' show CompilerTask, Measurer;
import '../common.dart';
import '../options.dart';
@@ -59,13 +60,44 @@
return measure(() async {
String targetName =
_options.compileForServer ? "dart2js_server" : "dart2js";
- String platform = targetName;
- if (_options.useNullSafety && !_options.useWeakNullSafetySemantics) {
- platform += "_nnbd_strong";
+
+ // We defer selecting the platform until we've resolved the NNBD mode.
+ String getPlatformFilename() {
+ String platform = targetName;
+ if ((_options.nullSafetyMode == NullSafetyMode.sound)) {
+ platform += "_nnbd_strong";
+ }
+ platform += "_platform.dill";
+ return platform;
}
- platform += "_platform.dill";
- var isDill = resolvedUri.path.endsWith('.dill');
+
ir.Component component;
+ var isDill = resolvedUri.path.endsWith('.dill');
+
+ // TODO(sigmund): remove after we unfork the sdk, and force null-safety to
+ // always be considered to be true.
+ void inferNullSafety() {
+ if (component.libraries.any((lib) =>
+ lib.isNonNullableByDefault && lib.importUri.scheme == 'dart')) {
+ _options.useNullSafety = true;
+ }
+ }
+
+ void inferNullSafetyMode(bool isSound) {
+ if (isSound) assert(_options.useNullSafety == true);
+ if (_options.nullSafetyMode == NullSafetyMode.unspecified) {
+ _options.nullSafetyMode =
+ isSound ? NullSafetyMode.sound : NullSafetyMode.unsound;
+ }
+ }
+
+ void validateNullSafety() {
+ assert(_options.nullSafetyMode != NullSafetyMode.unspecified);
+ if (_options.nullSafetyMode == NullSafetyMode.sound) {
+ assert(_options.useNullSafety);
+ }
+ }
+
if (isDill) {
component = new ir.Component();
Future<void> read(Uri uri) async {
@@ -75,11 +107,28 @@
}
await read(resolvedUri);
+
+ var isStrongDill =
+ component.mode == ir.NonNullableByDefaultCompiledMode.Strong;
+ var incompatibleNullSafetyMode =
+ isStrongDill ? NullSafetyMode.unsound : NullSafetyMode.sound;
+ if (_options.nullSafetyMode == incompatibleNullSafetyMode) {
+ var dillMode = isStrongDill ? 'sound' : 'unsound';
+ var option =
+ isStrongDill ? Flags.noSoundNullSafety : Flags.soundNullSafety;
+ throw ArgumentError("$resolvedUri was compiled with $dillMode null "
+ "safety and is incompatible with the '$option' option");
+ }
+ inferNullSafety();
+ inferNullSafetyMode(isStrongDill);
+ validateNullSafety();
+
if (_options.dillDependencies != null) {
// Modular compiles do not include the platform on the input dill
// either.
if (_options.platformBinaries != null) {
- await read(_options.platformBinaries.resolve(platform));
+ await read(
+ _options.platformBinaries.resolve(getPlatformFilename()));
}
for (Uri dependency in _options.dillDependencies) {
await read(dependency);
@@ -96,16 +145,34 @@
return null;
}
} else {
+ bool verbose = false;
+ Target target = Dart2jsTarget(targetName, TargetFlags());
+ fe.FileSystem fileSystem = CompilerFileSystem(_compilerInput);
+ fe.DiagnosticMessageHandler onDiagnostic =
+ (e) => reportFrontEndMessage(_reporter, e);
+ fe.CompilerOptions options = fe.CompilerOptions()
+ ..target = target
+ ..librariesSpecificationUri = _options.librariesSpecificationUri
+ ..packagesFileUri = _options.packageConfig
+ ..experimentalFlags = _options.languageExperiments
+ ..verbose = verbose
+ ..fileSystem = fileSystem
+ ..onDiagnostic = onDiagnostic;
+ bool isLegacy =
+ await fe.uriUsesLegacyLanguageVersion(resolvedUri, options);
+ inferNullSafetyMode(_options.useNullSafety && !isLegacy);
+
List<Uri> dependencies = [];
if (_options.platformBinaries != null) {
- dependencies.add(_options.platformBinaries.resolve(platform));
+ dependencies
+ .add(_options.platformBinaries.resolve(getPlatformFilename()));
}
if (_options.dillDependencies != null) {
dependencies.addAll(_options.dillDependencies);
}
initializedCompilerState = fe.initializeCompiler(
initializedCompilerState,
- new Dart2jsTarget(targetName, new TargetFlags()),
+ target,
_options.librariesSpecificationUri,
dependencies,
_options.packageConfig,
@@ -113,20 +180,11 @@
nnbdMode: _options.useLegacySubtyping
? fe.NnbdMode.Weak
: fe.NnbdMode.Strong);
- component = await fe.compile(
- initializedCompilerState,
- false,
- new CompilerFileSystem(_compilerInput),
- (e) => reportFrontEndMessage(_reporter, e),
- resolvedUri);
- }
- if (component == null) return null;
-
- // TODO(sigmund): remove after we unfork the sdk, and force null-safety to
- // always be considered to be true.
- if (component.libraries.any((lib) =>
- lib.isNonNullableByDefault && lib.importUri.scheme == 'dart')) {
- _options.useNullSafety = true;
+ component = await fe.compile(initializedCompilerState, verbose,
+ fileSystem, onDiagnostic, resolvedUri);
+ if (component == null) return null;
+ inferNullSafety();
+ validateNullSafety();
}
if (_options.cfeOnly) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index ce0599c..5b84ff7 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -9,6 +9,12 @@
import 'commandline_options.dart' show Flags;
import 'util/util.dart';
+enum NullSafetyMode {
+ unspecified,
+ unsound,
+ sound,
+}
+
/// Options used for controlling diagnostic messages.
abstract class DiagnosticOptions {
const DiagnosticOptions();
@@ -344,14 +350,22 @@
bool useNullSafety = false;
/// When null-safety is enabled, whether the compiler should emit code with
- /// weak or strong semantics.
- bool useWeakNullSafetySemantics = true;
+ /// unsound or sound semantics.
+ ///
+ /// If unspecified, the mode must be inferred from the entrypoint.
+ NullSafetyMode nullSafetyMode = NullSafetyMode.unspecified;
+ bool _soundNullSafety = false;
+ bool _noSoundNullSafety = false;
/// Whether to use legacy subtype semantics rather than null-safe semantics.
/// This is `true` if null-safety is disabled, i.e. all code is legacy code,
- /// or if weak null-safety semantics are being used, since we do not emit
+ /// or if unsound null-safety semantics are being used, since we do not emit
/// warnings.
- bool get useLegacySubtyping => !useNullSafety || useWeakNullSafetySemantics;
+ bool get useLegacySubtyping {
+ assert(nullSafetyMode != NullSafetyMode.unspecified,
+ "Null safety mode unspecified");
+ return !useNullSafety || (nullSafetyMode == NullSafetyMode.unsound);
+ }
/// The path to the file that contains the profiled allocations.
///
@@ -469,7 +483,8 @@
..codegenShards = _extractIntOption(options, '${Flags.codegenShards}=')
..cfeOnly = _hasOption(options, Flags.cfeOnly)
..debugGlobalInference = _hasOption(options, Flags.debugGlobalInference)
- ..useWeakNullSafetySemantics = !_hasOption(options, Flags.nullSafety);
+ .._soundNullSafety = _hasOption(options, Flags.soundNullSafety)
+ .._noSoundNullSafety = _hasOption(options, Flags.noSoundNullSafety);
}
void validate() {
@@ -491,6 +506,14 @@
throw ArgumentError("'${Flags.legacyJavaScript}' incompatible with "
"'${Flags.noLegacyJavaScript}'");
}
+ if (_soundNullSafety && _noSoundNullSafety) {
+ throw ArgumentError("'${Flags.soundNullSafety}' incompatible with "
+ "'${Flags.noSoundNullSafety}'");
+ }
+ if (!useNullSafety && _soundNullSafety) {
+ throw ArgumentError("'${Flags.soundNullSafety}' requires the "
+ "'non-nullable' experiment to be enabled");
+ }
}
void deriveOptions() {
@@ -511,6 +534,9 @@
useNullSafety = true;
}
+ if (_soundNullSafety) nullSafetyMode = NullSafetyMode.sound;
+ if (_noSoundNullSafety) nullSafetyMode = NullSafetyMode.unsound;
+
if (optimizationLevel != null) {
if (optimizationLevel == 0) {
disableInlining = true;
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 86b00ee..06de6f8 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -8,6 +8,7 @@
import 'package:kernel/binary/ast_to_binary.dart' as ir;
import '../../compiler_new.dart' as api;
import '../backend_strategy.dart';
+import '../commandline_options.dart' show Flags;
import '../common/codegen.dart';
import '../common/tasks.dart';
import '../diagnostics/diagnostic_listener.dart';
@@ -98,11 +99,31 @@
new ir.BinaryBuilder(dillInput.data).readComponent(component);
return component;
});
+
+ var isStrongDill =
+ component.mode == ir.NonNullableByDefaultCompiledMode.Strong;
+ var incompatibleNullSafetyMode =
+ isStrongDill ? NullSafetyMode.unsound : NullSafetyMode.sound;
+ if (_options.nullSafetyMode == incompatibleNullSafetyMode) {
+ var dillMode = isStrongDill ? 'sound' : 'unsound';
+ var option =
+ isStrongDill ? Flags.noSoundNullSafety : Flags.soundNullSafety;
+ throw ArgumentError("${_options.entryPoint} was compiled with $dillMode "
+ "null safety and is incompatible with the '$option' option");
+ }
+
if (component.libraries.any((lib) =>
lib.isNonNullableByDefault && lib.importUri.scheme == 'dart')) {
_options.useNullSafety = true;
}
+ if (component.mode == ir.NonNullableByDefaultCompiledMode.Strong) {
+ _options.nullSafetyMode = NullSafetyMode.sound;
+ assert(_options.useNullSafety);
+ } else {
+ _options.nullSafetyMode = NullSafetyMode.unsound;
+ }
+
return await measureIoSubtask('deserialize data', () async {
_reporter.log('Reading data from ${_options.readDataUri}');
api.Input<List<int>> dataInput = await _provider
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ae77337..1082a00 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4394,13 +4394,8 @@
function.requiredParameterCount ==
function.positionalParameters.length &&
function.namedParameters.isEmpty) {
- push(new HForeignCode(
- js.js.expressionTemplateYielding(_emitter
- .staticFunctionAccess(_elementMap.getMethod(procedure))),
- _abstractValueDomain.dynamicType,
- <HInstruction>[],
- nativeBehavior: NativeBehavior.PURE,
- foreignFunction: _elementMap.getMethod(procedure)));
+ push(HFunctionReference(_elementMap.getMethod(procedure),
+ _abstractValueDomain.dynamicType));
return true;
}
problem = 'does not handle a closure with optional parameters';
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index db213ca..cbb4bc0 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2285,6 +2285,13 @@
}
@override
+ visitFunctionReference(HFunctionReference node) {
+ FunctionEntity element = node.element;
+ _registry.registerStaticUse(StaticUse.implicitInvoke(element));
+ push(_emitter.staticFunctionAccess(element));
+ }
+
+ @override
visitLocalGet(HLocalGet node) {
use(node.receiver);
}
@@ -2409,11 +2416,6 @@
// TODO(sra): Tell world.nativeEnqueuer about the types created here.
registerForeignTypes(node);
-
- if (node.foreignFunction != null) {
- _registry?.registerStaticUse(
- new StaticUse.implicitInvoke(node.foreignFunction));
- }
}
@override
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index fce8ad8..e7ea8ac 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -45,6 +45,7 @@
R visitExitTry(HExitTry node);
R visitFieldGet(HFieldGet node);
R visitFieldSet(HFieldSet node);
+ R visitFunctionReference(HFunctionReference node);
R visitInvokeExternal(HInvokeExternal node);
R visitForeignCode(HForeignCode node);
R visitGetLength(HGetLength node);
@@ -471,6 +472,8 @@
@override
visitFieldSet(HFieldSet node) => visitFieldAccess(node);
@override
+ visitFunctionReference(HFunctionReference node) => visitInstruction(node);
+ @override
visitInvokeExternal(HInvokeExternal node) => visitInstruction(node);
@override
visitForeignCode(HForeignCode node) => visitInstruction(node);
@@ -1083,13 +1086,14 @@
static const int STATIC_TYPECODE = 21;
static const int STATIC_STORE_TYPECODE = 22;
static const int FIELD_GET_TYPECODE = 23;
- static const int TYPE_CONVERSION_TYPECODE = 24;
- static const int TYPE_KNOWN_TYPECODE = 25;
- static const int INVOKE_STATIC_TYPECODE = 26;
- static const int INDEX_TYPECODE = 27;
- static const int IS_TYPECODE = 28;
- static const int INVOKE_DYNAMIC_TYPECODE = 29;
- static const int SHIFT_RIGHT_TYPECODE = 30;
+ static const int FUNCTION_REFERENCE_TYPECODE = 24;
+ static const int TYPE_CONVERSION_TYPECODE = 25;
+ static const int TYPE_KNOWN_TYPECODE = 26;
+ static const int INVOKE_STATIC_TYPECODE = 27;
+ static const int INDEX_TYPECODE = 28;
+ static const int IS_TYPECODE = 29;
+ static const int INVOKE_DYNAMIC_TYPECODE = 30;
+ static const int SHIFT_RIGHT_TYPECODE = 31;
static const int TRUNCATING_DIVIDE_TYPECODE = 36;
static const int IS_VIA_INTERCEPTOR_TYPECODE = 37;
@@ -2166,6 +2170,28 @@
String toString() => "FieldSet(element=$element,type=$instructionType)";
}
+// Raw reference to a function.
+class HFunctionReference extends HInstruction {
+ FunctionEntity element;
+ HFunctionReference(this.element, AbstractValue type) : super([], type) {
+ sideEffects.clearAllSideEffects();
+ sideEffects.clearAllDependencies();
+ setUseGvn();
+ }
+
+ @override
+ accept(HVisitor visitor) => visitor.visitFunctionReference(this);
+
+ @override
+ int typeCode() => HInstruction.FUNCTION_REFERENCE_TYPECODE;
+ @override
+ bool typeEquals(other) => other is HFunctionReference;
+ @override
+ bool dataEquals(HFunctionReference other) => element == other.element;
+ @override
+ String toString() => "FunctionReference($element)";
+}
+
class HGetLength extends HInstruction {
final bool isAssignable;
HGetLength(HInstruction receiver, AbstractValue type,
@@ -2412,14 +2438,12 @@
@override
final NativeBehavior nativeBehavior;
NativeThrowBehavior throwBehavior;
- final FunctionEntity foreignFunction;
HForeignCode(this.codeTemplate, AbstractValue type, List<HInstruction> inputs,
{this.isStatement: false,
SideEffects effects,
NativeBehavior nativeBehavior,
- NativeThrowBehavior throwBehavior,
- this.foreignFunction})
+ NativeThrowBehavior throwBehavior})
: this.nativeBehavior = nativeBehavior,
this.throwBehavior = throwBehavior,
super(type, inputs) {
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 5bfb428..1c7f7ae 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -261,6 +261,11 @@
}
@override
+ String visitFunctionReference(HFunctionReference node) {
+ return 'FunctionReference: ${node.element}';
+ }
+
+ @override
String visitReadModifyWrite(HReadModifyWrite node) {
String fieldName = node.element.name;
String receiverId = temporaryId(node.receiver);
diff --git a/pkg/dartdev/bin/dartdev.dart b/pkg/dartdev/bin/dartdev.dart
index 7968056..a68e139 100644
--- a/pkg/dartdev/bin/dartdev.dart
+++ b/pkg/dartdev/bin/dartdev.dart
@@ -13,12 +13,13 @@
try {
dynamic result = await runner.run(args);
exit(result is int ? result : 0);
- } catch (e) {
+ } catch (e, st) {
if (e is UsageException) {
stderr.writeln('$e');
exit(64);
} else {
stderr.writeln('$e');
+ stderr.writeln('$st');
exit(1);
}
}
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 4249df8..25fce07 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -246,6 +246,9 @@
bool visitLet(Let node) => isNullable(node.body);
@override
+ bool visitBlockExpression(BlockExpression node) => isNullable(node.value);
+
+ @override
bool visitInstantiation(Instantiation node) => false;
bool isNotNullAnnotation(Expression value) =>
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index d39c7e6..7c11494 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -253,7 +253,7 @@
'() → dart.core::Null? => null, f');
});
- test('cascades (kernel let)', () async {
+ test('cascades (kernel BlockExpression)', () async {
// `null..toString()` evaluates to `null` so it is nullable.
await expectNotNull('main() { null..toString(); }', '');
await expectAllNotNull('main() { 1..toString(); }');
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index 6004fc5..d213c3a 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,8 +1,8 @@
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3719|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7908|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7909|5|97|Const constructors can't throw exceptions.
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions.
ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions.
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3717|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7906|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7907|3|5|Only redirecting factory constructors can be declared to be 'const'.
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'.
ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 9cb036e..4a7ef9d 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -51,6 +51,7 @@
export 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
show
DiagnosticMessage,
+ DiagnosticMessageHandler,
getMessageCharOffset,
getMessageHeaderText,
getMessageLength,
@@ -109,6 +110,9 @@
export '../api_prototype/kernel_generator.dart' show kernelForProgram;
+export '../api_prototype/language_version.dart'
+ show uriUsesLegacyLanguageVersion;
+
export '../api_prototype/standard_file_system.dart' show DataFileSystemEntity;
export '../base/nnbd_mode.dart' show NnbdMode;
@@ -135,17 +139,21 @@
Uri librariesSpecificationUri,
List<Uri> additionalDills,
Uri packagesFileUri,
- {List<Uri> dependencies,
- Map<ExperimentalFlag, bool> experimentalFlags,
+ {Map<ExperimentalFlag, bool> experimentalFlags,
bool verify: false,
NnbdMode nnbdMode}) {
additionalDills.sort((a, b) => a.toString().compareTo(b.toString()));
+ // We don't check `target` because it doesn't support '==' and each
+ // compilation passes a fresh target. However, we pass a logically identical
+ // target each time, so it is safe to assume that it never changes.
if (oldState != null &&
oldState.options.packagesFileUri == packagesFileUri &&
oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
equalLists(oldState.options.additionalDills, additionalDills) &&
- equalMaps(oldState.options.experimentalFlags, experimentalFlags)) {
+ equalMaps(oldState.options.experimentalFlags, experimentalFlags) &&
+ oldState.options.verify == verify &&
+ oldState.options.nnbdMode == nnbdMode) {
return oldState;
}
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 f6dc730..db05cf8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -356,13 +356,14 @@
expression, const UnknownType(), !inferrer.isTopLevel,
isVoidAllowed: true));
}
- Expression replacement = createVariableGet(node.variable);
- for (int index = expressionResults.length - 1; index >= 0; index--) {
- replacement = createLet(
- createVariable(expressionResults[index].expression, const VoidType()),
- replacement);
+ List<Statement> body = [];
+ for (int index = 0; index < expressionResults.length; index++) {
+ body.add(_createExpressionStatement(expressionResults[index].expression));
}
+ Expression replacement = _createBlockExpression(node.variable.fileOffset,
+ _createBlock(body), createVariableGet(node.variable));
+
if (node.isNullAware) {
replacement =
nullAwareGuard.createExpression(result.inferredType, replacement);
@@ -373,6 +374,24 @@
return new ExpressionInferenceResult(result.inferredType, replacement);
}
+ Block _createBlock(List<Statement> statements) {
+ return new Block(statements);
+ }
+
+ BlockExpression _createBlockExpression(
+ int fileOffset, Block body, Expression value) {
+ assert(fileOffset != null);
+ assert(fileOffset != TreeNode.noOffset);
+ return new BlockExpression(body, value)..fileOffset = fileOffset;
+ }
+
+ ExpressionStatement _createExpressionStatement(Expression expression) {
+ assert(expression != null);
+ assert(expression.fileOffset != TreeNode.noOffset);
+ return new ExpressionStatement(expression)
+ ..fileOffset = expression.fileOffset;
+ }
+
@override
ExpressionInferenceResult visitConditionalExpression(
ConditionalExpression node, DartType typeContext) {
@@ -2593,7 +2612,8 @@
inferredType)
..fileOffset = node.fileOffset;
replacement =
- new Let(node.variable, conditional..fileOffset = node.fileOffset);
+ new Let(node.variable, conditional..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset;
} else {
// Encode `o.a ??= b` as:
//
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index bc08e07..f2fab9d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -32,8 +32,8 @@
// Generate:
//
// if (!_#isSet#field) {
- // _#isSet#field = true
// _#field = <init>;
+ // _#isSet#field = true
// }
// return _#field;
return new Block(<Statement>[
@@ -42,11 +42,11 @@
..fileOffset = fileOffset,
new Block(<Statement>[
new ExpressionStatement(
- createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
- ..fileOffset = fileOffset)
+ createVariableWrite(initializer)..fileOffset = fileOffset)
..fileOffset = fileOffset,
new ExpressionStatement(
- createVariableWrite(initializer)..fileOffset = fileOffset)
+ createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
+ ..fileOffset = fileOffset)
..fileOffset = fileOffset,
]),
null)
@@ -128,8 +128,8 @@
// if (!_#isSet#field) {
// var temp = <init>;
// if (_#isSet#field) throw '...'
- // _#isSet#field = true
// _#field = temp;
+ // _#isSet#field = true
// }
// return _#field;
return new Block(<Statement>[
@@ -144,12 +144,12 @@
null)
..fileOffset = fileOffset,
new ExpressionStatement(
- createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
+ createVariableWrite(
+ new VariableGet(temp)..fileOffset = fileOffset)
..fileOffset = fileOffset)
..fileOffset = fileOffset,
new ExpressionStatement(
- createVariableWrite(
- new VariableGet(temp)..fileOffset = fileOffset)
+ createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
..fileOffset = fileOffset)
..fileOffset = fileOffset,
]),
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 225546e..fc54be6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -4,33 +4,11 @@
library fasta.verifier;
+import 'dart:core' hide MapEntry;
+
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-import 'package:kernel/ast.dart'
- show
- AsExpression,
- BottomType,
- Class,
- Component,
- DartType,
- DynamicType,
- ExpressionStatement,
- Field,
- FunctionType,
- InterfaceType,
- InvalidType,
- Library,
- Member,
- NeverType,
- Nullability,
- Procedure,
- StaticInvocation,
- SuperMethodInvocation,
- SuperPropertyGet,
- SuperPropertySet,
- TreeNode,
- TypeParameter,
- VoidType;
+import 'package:kernel/ast.dart';
import 'package:kernel/transformations/flags.dart' show TransformerFlag;
@@ -39,7 +17,11 @@
import '../compiler_context.dart' show CompilerContext;
import '../fasta_codes.dart'
- show LocatedMessage, noLength, templateInternalProblemVerificationError;
+ show
+ LocatedMessage,
+ messageVerificationErrorOriginContext,
+ noLength,
+ templateInternalProblemVerificationError;
import '../type_inference/type_schema.dart' show UnknownType;
@@ -56,14 +38,91 @@
class FastaVerifyingVisitor extends VerifyingVisitor {
final List<LocatedMessage> errors = <LocatedMessage>[];
- Library currentLibrary = null;
Uri fileUri;
+ final List<TreeNode> treeNodeStack = <TreeNode>[];
final bool skipPlatform;
FastaVerifyingVisitor(bool isOutline, bool afterConst, this.skipPlatform)
: super(isOutline: isOutline, afterConst: afterConst);
+ /// Invoked by all visit methods if the visited node is a [TreeNode].
+ void enterTreeNode(TreeNode node) {
+ treeNodeStack.add(node);
+ }
+
+ /// Invoked by all visit methods if the visited node is a [TreeNode].
+ void exitTreeNode(TreeNode node) {
+ if (treeNodeStack.isEmpty) {
+ throw new StateError("Attempting to exit tree node '${node}' "
+ "when the tree node stack is empty.");
+ }
+ if (!identical(treeNodeStack.last, node)) {
+ throw new StateError("Attempting to exit tree node '${node}' "
+ "when another node '${treeNodeStack.last}' is active.");
+ }
+ treeNodeStack.removeLast();
+ }
+
+ TreeNode getLastSeenTreeNode({bool withLocation = false}) {
+ assert(treeNodeStack.isNotEmpty);
+ for (int i = treeNodeStack.length - 1; i >= 0; --i) {
+ TreeNode node = treeNodeStack[i];
+ if (withLocation && !_hasLocation(node)) continue;
+ return node;
+ }
+ return null;
+ }
+
+ TreeNode getSameLibraryLastSeenTreeNode({bool withLocation = false}) {
+ if (treeNodeStack.isEmpty) return null;
+ if (currentLibrary == null || currentLibrary.fileUri == null) return null;
+
+ for (int i = treeNodeStack.length - 1; i >= 0; --i) {
+ TreeNode node = treeNodeStack[i];
+ if (withLocation && !_hasLocation(node)) continue;
+ if (node.location?.file != null &&
+ node.location.file == currentLibrary.fileUri) {
+ return node;
+ }
+ }
+ return null;
+ }
+
+ static bool _hasLocation(TreeNode node) {
+ return node.location != null &&
+ node.location.file != null &&
+ node.fileOffset != null &&
+ node.fileOffset != -1;
+ }
+
+ static bool _isInSameLibrary(Library library, TreeNode node) {
+ if (library == null) return false;
+ if (library.fileUri == null) return false;
+ if (node.location == null) return false;
+ if (node.location.file == null) return false;
+
+ return library.fileUri == node.location.file;
+ }
+
+ TreeNode get localContext {
+ TreeNode result = getSameLibraryLastSeenTreeNode(withLocation: true);
+ if (result == null &&
+ currentClassOrMember != null &&
+ _isInSameLibrary(currentLibrary, currentClassOrMember)) {
+ result = currentClassOrMember;
+ }
+ return result;
+ }
+
+ TreeNode get remoteContext {
+ TreeNode result = getLastSeenTreeNode(withLocation: true);
+ if (result != null && _isInSameLibrary(currentLibrary, result)) {
+ result = null;
+ }
+ return result;
+ }
+
Uri checkLocation(TreeNode node, String name, Uri fileUri) {
if (name == null || name.contains("#")) {
// TODO(ahe): Investigate if these checks can be enabled:
@@ -109,20 +168,29 @@
}
@override
- problem(TreeNode node, String details, {TreeNode context}) {
- node ??= (context ?? this.context);
+ problem(TreeNode node, String details, {TreeNode context, TreeNode origin}) {
+ node ??= (context ?? currentClassOrMember);
int offset = node?.fileOffset ?? -1;
Uri file = node?.location?.file ?? fileUri;
Uri uri = file == null ? null : file;
LocatedMessage message = templateInternalProblemVerificationError
.withArguments(details)
.withLocation(uri, offset, noLength);
- CompilerContext.current.report(message, Severity.error);
+ List<LocatedMessage> contextMessages;
+ if (origin != null) {
+ contextMessages = [
+ messageVerificationErrorOriginContext.withLocation(
+ origin.location.file, origin.fileOffset, noLength)
+ ];
+ }
+ CompilerContext.current
+ .report(message, Severity.error, context: contextMessages);
errors.add(message);
}
@override
- visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
+ enterTreeNode(node);
super.visitAsExpression(node);
if (node.fileOffset == -1) {
TreeNode parent = node.parent;
@@ -132,45 +200,57 @@
}
problem(parent, "No offset for $node", context: node);
}
+ exitTreeNode(node);
}
@override
- visitExpressionStatement(ExpressionStatement node) {
+ void visitExpressionStatement(ExpressionStatement node) {
// Bypass verification of the [StaticGet] in [RedirectingFactoryBody] as
// this is a static get without a getter.
if (node is! RedirectingFactoryBody) {
+ enterTreeNode(node);
super.visitExpressionStatement(node);
+ exitTreeNode(node);
}
}
@override
- visitLibrary(Library node) {
+ void visitLibrary(Library node) {
// Issue(http://dartbug.com/32530)
if (skipPlatform && node.importUri.scheme == 'dart') {
return;
}
+
+ enterTreeNode(node);
fileUri = checkLocation(node, node.name, node.fileUri);
currentLibrary = node;
super.visitLibrary(node);
currentLibrary = null;
+ exitTreeNode(node);
}
@override
- visitClass(Class node) {
+ void visitClass(Class node) {
+ enterTreeNode(node);
fileUri = checkLocation(node, node.name, node.fileUri);
super.visitClass(node);
+ exitTreeNode(node);
}
@override
- visitField(Field node) {
+ void visitField(Field node) {
+ enterTreeNode(node);
fileUri = checkLocation(node, node.name.name, node.fileUri);
super.visitField(node);
+ exitTreeNode(node);
}
@override
- visitProcedure(Procedure node) {
+ void visitProcedure(Procedure node) {
+ enterTreeNode(node);
fileUri = checkLocation(node, node.name.name, node.fileUri);
super.visitProcedure(node);
+ exitTreeNode(node);
}
bool isNullType(DartType node) {
@@ -183,40 +263,99 @@
return false;
}
- @override
- defaultDartType(DartType node) {
- if (node is UnknownType) {
- // Note: we can't pass [node] to [problem] because it's not a [TreeNode].
- problem(null, "Unexpected appearance of the unknown type.");
- }
- bool neverLegacy = isNullType(node) ||
- node is DynamicType ||
- node is InvalidType ||
+ bool isFutureOrClass(Class c) {
+ return c.name == "FutureOr" &&
+ c.enclosingLibrary.importUri.scheme == "dart" &&
+ c.enclosingLibrary.importUri.path == "async";
+ }
+
+ bool isObjectClass(Class c) {
+ return c.name == "Object" &&
+ c.enclosingLibrary.importUri.scheme == "dart" &&
+ c.enclosingLibrary.importUri.path == "core";
+ }
+
+ bool isTopType(DartType node) {
+ return node is DynamicType ||
node is VoidType ||
- node is NeverType ||
- node is BottomType;
- bool expectedLegacy =
- !currentLibrary.isNonNullableByDefault && !neverLegacy;
- if (expectedLegacy && node.nullability != Nullability.legacy) {
- problem(
- null, "Found a non-legacy type '${node}' in an opted-out library.");
+ node is InterfaceType &&
+ isObjectClass(node.classNode) &&
+ (node.nullability == Nullability.nullable ||
+ node.nullability == Nullability.legacy) ||
+ node is InterfaceType &&
+ isFutureOrClass(node.classNode) &&
+ isTopType(node.typeArguments.single);
+ }
+
+ bool isFutureOrNull(DartType node) {
+ return isNullType(node) ||
+ node is InterfaceType &&
+ isFutureOrClass(node.classNode) &&
+ isFutureOrNull(node.typeArguments.single);
+ }
+
+ @override
+ void defaultDartType(DartType node) {
+ final TreeNode localContext = this.localContext;
+ final TreeNode remoteContext = this.remoteContext;
+
+ if (node is UnknownType) {
+ problem(localContext, "Unexpected appearance of the unknown type.",
+ origin: remoteContext);
}
- Nullability nodeNullability =
- node is InvalidType ? Nullability.undetermined : node.nullability;
- if (currentLibrary.isNonNullableByDefault &&
- nodeNullability == Nullability.legacy) {
- problem(null, "Found a legacy type '${node}' in an opted-in library.");
+
+ bool isTypeCast = localContext != null &&
+ localContext is AsExpression &&
+ localContext.isTypeError;
+ // Don't check cases like foo(x as{TypeError} T). In cases where foo comes
+ // from a library with a different opt-in status than the current library,
+ // the check may not be necessary. For now, just skip all type-error casts.
+ // TODO(dmitryas): Implement a more precise analysis.
+ bool isFromAnotherLibrary = remoteContext != null || isTypeCast;
+
+ // Checking for non-legacy types in opt-out libraries.
+ {
+ bool neverLegacy = isNullType(node) ||
+ isFutureOrNull(node) ||
+ isTopType(node) ||
+ node is InvalidType ||
+ node is NeverType ||
+ node is BottomType;
+ // TODO(dmitryas): Consider checking types coming from other libraries.
+ bool expectedLegacy = !isFromAnotherLibrary &&
+ !currentLibrary.isNonNullableByDefault &&
+ !neverLegacy;
+ if (expectedLegacy && node.nullability != Nullability.legacy) {
+ problem(localContext,
+ "Found a non-legacy type '${node}' in an opted-out library.",
+ origin: remoteContext);
+ }
}
+
+ // Checking for legacy types in opt-in libraries.
+ {
+ Nullability nodeNullability =
+ node is InvalidType ? Nullability.undetermined : node.nullability;
+ // TODO(dmitryas): Consider checking types coming from other libraries.
+ if (!isFromAnotherLibrary &&
+ currentLibrary.isNonNullableByDefault &&
+ nodeNullability == Nullability.legacy) {
+ problem(localContext,
+ "Found a legacy type '${node}' in an opted-in library.",
+ origin: remoteContext);
+ }
+ }
+
super.defaultDartType(node);
}
@override
- visitFunctionType(FunctionType node) {
+ void visitFunctionType(FunctionType node) {
if (node.typeParameters.isNotEmpty) {
for (TypeParameter typeParameter in node.typeParameters) {
if (typeParameter.parent != null) {
problem(
- null,
+ localContext,
"Type parameters of function types shouldn't have parents: "
"$node.");
}
@@ -226,37 +365,52 @@
}
@override
- visitInterfaceType(InterfaceType node) {
+ void visitInterfaceType(InterfaceType node) {
if (isNullType(node) && node.nullability != Nullability.nullable) {
- problem(null, "Found a not nullable Null type: ${node}");
+ problem(localContext, "Found a not nullable Null type: ${node}");
}
super.visitInterfaceType(node);
}
@override
- visitSuperMethodInvocation(SuperMethodInvocation node) {
+ void visitSuperMethodInvocation(SuperMethodInvocation node) {
+ enterTreeNode(node);
checkSuperInvocation(node);
super.visitSuperMethodInvocation(node);
+ exitTreeNode(node);
}
@override
- visitSuperPropertyGet(SuperPropertyGet node) {
+ void visitSuperPropertyGet(SuperPropertyGet node) {
+ enterTreeNode(node);
checkSuperInvocation(node);
super.visitSuperPropertyGet(node);
+ exitTreeNode(node);
}
@override
- visitSuperPropertySet(SuperPropertySet node) {
+ void visitSuperPropertySet(SuperPropertySet node) {
+ enterTreeNode(node);
checkSuperInvocation(node);
super.visitSuperPropertySet(node);
+ exitTreeNode(node);
}
@override
- visitStaticInvocation(StaticInvocation node) {
+ void visitStaticInvocation(StaticInvocation node) {
+ enterTreeNode(node);
super.visitStaticInvocation(node);
RedirectingFactoryBody body = getRedirectingFactoryBody(node.target);
if (body != null) {
problem(node, "Attempt to invoke redirecting factory.");
}
+ exitTreeNode(node);
+ }
+
+ @override
+ void defaultTreeNode(TreeNode node) {
+ enterTreeNode(node);
+ super.defaultTreeNode(node);
+ exitTreeNode(node);
}
}
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 99782aa..e2ce926 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1736,6 +1736,10 @@
#string
severity: INTERNAL_PROBLEM
+VerificationErrorOriginContext:
+ template: "The node most likely is taken from here by a transformer."
+ severity: CONTEXT
+
InternalProblemDebugAbort:
template: "Compilation aborted due to fatal '#name' at:\n#string"
severity: INTERNAL_PROBLEM
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
index 048c81d..5920035 100644
--- a/pkg/front_end/test/comments_on_certain_arguments_tool.dart
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -15,9 +15,6 @@
stdin,
stdout;
-import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;
-import 'package:_fe_analyzer_shared/src/parser/forwarding_listener.dart'
- show NullListener;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
show CommentToken, Token;
@@ -88,7 +85,7 @@
for (Library library in component.libraries) {
if (library.importUri.scheme == "dart") continue;
- // This isn't perfect because of parts, but (for now it'll do).
+ // This isn't perfect because of parts, but (for now) it'll do.
for (Uri uri in libUris) {
if (library.fileUri.toString().startsWith(uri.toString())) {
library.accept(new InvocationVisitor());
@@ -241,7 +238,7 @@
}
}
if (wantComment) {
- check(invocation, i, positionalParameters[i],
+ check(arguments.positional[i], i, positionalParameters[i], node,
"/* ${positionalParameters[i].name} = */");
}
}
@@ -250,86 +247,26 @@
Map<Uri, Token> cache = {};
-void check(InvocationExpression invocation, int parameterNumber,
- VariableDeclaration parameter, String expectedComment) {
- if (invocation.name.name == "==") return;
- if (invocation.name.name == "[]=") return;
- if (invocation.name.name == "[]") return;
- if (invocation.name.name == "<") return;
- if (invocation.name.name == "<=") return;
- if (invocation.name.name == ">") return;
- if (invocation.name.name == ">=") return;
- if (invocation.name.name == "+") return;
- if (invocation.name.name == "-") return;
- if (invocation.name.name == "*") return;
- if (invocation.name.name == "/") return;
- if (invocation.name.name == "<<") return;
- if (invocation.name.name == "<<<") return;
- if (invocation.name.name == ">>") return;
- if (invocation.name.name == "|=") return;
- if (invocation.name.name == "|") return;
- if (invocation.name.name == "&") return;
- if (invocation.name.name == "~/") return;
- Location location = invocation.location;
+void check(
+ Expression argumentExpression,
+ int parameterNumber,
+ VariableDeclaration parameter,
+ NamedNode targetNode,
+ String expectedComment) {
+ if (targetNode is Procedure && targetNode.kind == ProcedureKind.Operator) {
+ // Operator calls doesn't look like 'regular' method calls.
+ return;
+ }
+ if (argumentExpression.fileOffset == -1) return;
+ Location location = argumentExpression.location;
Token token = cache[location.file];
- while (token.offset != invocation.fileOffset) {
+ while (token.offset != argumentExpression.fileOffset) {
token = token.next;
if (token.isEof) {
- print("Couldn't find token for $invocation...");
- return;
+ throw "Couldn't find token for $argumentExpression "
+ "(${argumentExpression.fileOffset}).";
}
}
- if (token.lexeme != invocation.name.name) {
- bool ignore = false;
- // Check if the next tokens are ".<what we're looking for>".
- if (token.next.lexeme == "." &&
- token.next.next.lexeme == invocation.name.name) {
- ignore = true;
- token = token.next.next;
- } else if (invocation is StaticInvocation) {
- Procedure p = invocation.targetReference.node;
- ignore = p.isFactory;
- }
- if (invocation is ConstructorInvocation || ignore) {
- // ignore that... E.g. new Foo() will have name ''.
- } else {
- Location calculatedLocation =
- component.getLocation(location.file, token.offset);
- throw "Expected to find ${invocation.name.name} but "
- "found ${token.lexeme} at $calculatedLocation "
- "(would have checked for comment $expectedComment)";
- }
- }
- token = token.next;
- while (token.lexeme == ".") {
- token = token.next.next;
- }
- if (token.lexeme == "<") {
- if (token.endGroup != null) {
- token = token.endGroup.next;
- }
- }
- while (token.lexeme == ".") {
- token = token.next.next;
- }
- if (token.lexeme != "(") {
- Location calculatedLocation =
- component.getLocation(location.file, token.offset);
- throw "Expected to find ( but found ${token.lexeme} "
- "at $calculatedLocation"
- " (would have checked for comment $expectedComment)";
- }
- if (parameterNumber > 0) {
- Parser parser = new Parser(new NullListener());
- for (int i = 0; i < parameterNumber; i++) {
- token = parser.parseExpression(token);
- if (token.next.lexeme != ",") {
- throw "Expected to find , but found ${token.next.lexeme}";
- }
- token = token.next;
- }
- }
- token = token.next;
bool foundComment = false;
CommentToken commentToken = token.precedingComments;
while (commentToken != null) {
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
index 6e5d2e6..3ae2d7b 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.expect
@@ -24,14 +24,16 @@
operator - = self::Extension1|-;
}
static method Extension1|[](final self::C* #this, core::int* index) → self::C*
- return let final self::C* #t1 = #this in let final void #t2 = let final self::C* #t3 = #t1 in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(index.{core::num::+}(1)) in #t1;
+ return let final self::C* #t1 = #this in block {
+ let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
+ } =>#t1;
static method Extension1|[]=(final self::C* #this, core::int* index, self::C* other) → void
- return let final self::C* #t4 = #this in #t4.{self::C::value} = #t4.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
+ return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
static method Extension1|-(final self::C* #this, core::int* val) → self::C*
return #this;
static method main() → dynamic {
self::C* c = new self::C::•();
- let final self::C* #t5 = c in let final core::int* #t6 = 42 in let final self::C* #t7 = self::Extension1|-(self::Extension1|[](#t5, #t6), 1) in let final void #t8 = self::Extension1|[]=(#t5, #t6, #t7) in #t7;
- let final self::C* #t9 = c in let final core::int* #t10 = 42 in self::Extension1|[]=(#t9, #t10, self::Extension1|-(self::Extension1|[](#t9, #t10), 1));
+ let final self::C* #t4 = c in let final core::int* #t5 = 42 in let final self::C* #t6 = self::Extension1|-(self::Extension1|[](#t4, #t5), 1) in let final void #t7 = self::Extension1|[]=(#t4, #t5, #t6) in #t6;
+ let final self::C* #t8 = c in let final core::int* #t9 = 42 in self::Extension1|[]=(#t8, #t9, self::Extension1|-(self::Extension1|[](#t8, #t9), 1));
self::Extension1|[]=(c, 42, self::Extension1|-(self::Extension1|[](c, 42), 1));
}
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
index 6e5d2e6..3ae2d7b 100644
--- a/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.strong.transformed.expect
@@ -24,14 +24,16 @@
operator - = self::Extension1|-;
}
static method Extension1|[](final self::C* #this, core::int* index) → self::C*
- return let final self::C* #t1 = #this in let final void #t2 = let final self::C* #t3 = #t1 in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(index.{core::num::+}(1)) in #t1;
+ return let final self::C* #t1 = #this in block {
+ let final self::C* #t2 = #t1 in #t2.{self::C::value} = #t2.{self::C::value}.{core::num::+}(index.{core::num::+}(1));
+ } =>#t1;
static method Extension1|[]=(final self::C* #this, core::int* index, self::C* other) → void
- return let final self::C* #t4 = #this in #t4.{self::C::value} = #t4.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
+ return let final self::C* #t3 = #this in #t3.{self::C::value} = #t3.{self::C::value}.{core::num::+}(other.{self::C::value}.{core::num::+}(index).{core::num::+}(1));
static method Extension1|-(final self::C* #this, core::int* val) → self::C*
return #this;
static method main() → dynamic {
self::C* c = new self::C::•();
- let final self::C* #t5 = c in let final core::int* #t6 = 42 in let final self::C* #t7 = self::Extension1|-(self::Extension1|[](#t5, #t6), 1) in let final void #t8 = self::Extension1|[]=(#t5, #t6, #t7) in #t7;
- let final self::C* #t9 = c in let final core::int* #t10 = 42 in self::Extension1|[]=(#t9, #t10, self::Extension1|-(self::Extension1|[](#t9, #t10), 1));
+ let final self::C* #t4 = c in let final core::int* #t5 = 42 in let final self::C* #t6 = self::Extension1|-(self::Extension1|[](#t4, #t5), 1) in let final void #t7 = self::Extension1|[]=(#t4, #t5, #t6) in #t6;
+ let final self::C* #t8 = c in let final core::int* #t9 = 42 in self::Extension1|[]=(#t8, #t9, self::Extension1|-(self::Extension1|[](#t8, #t9), 1));
self::Extension1|[]=(c, 42, self::Extension1|-(self::Extension1|[](c, 42), 1));
}
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.expect
index ee50ed9..33c1f7c 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.expect
@@ -10,7 +10,9 @@
: super core::Object::•()
;
method m() → asy::Future<core::List<core::int*>*>* async
- return let final core::List<core::int*>* #t1 = <core::int*>[] in let final void #t2 = #t1.{core::List::add}(await this.{self::C::_m}()) in #t1;
+ return let final core::List<core::int*>* #t1 = <core::int*>[] in block {
+ #t1.{core::List::add}(await this.{self::C::_m}());
+ } =>#t1;
method _m() → asy::Future<core::int*>* async
return 42;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
index da55c50..0bb1652 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
@@ -25,7 +25,8 @@
{
final core::List<core::int*>* #t1 = <core::int*>[];
[yield] let dynamic #t2 = asy::_awaitHelper(this.{self::C::_m}(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = let final void #t3 = #t1.{core::List::add}(_in::unsafeCast<core::int*>(:result)) in #t1;
+ #t1.{core::List::add}(_in::unsafeCast<core::int*>(:result));
+ :return_value = block {} =>#t1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -91,7 +92,7 @@
try {
#L3:
{
- [yield] let dynamic #t4 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t3 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
self::expect(42, _in::unsafeCast<core::List<core::int*>*>(:result).{core::Iterable::first});
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/general/bug33206.dart.strong.expect b/pkg/front_end/testcases/general/bug33206.dart.strong.expect
index 8653700..2083c84 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.strong.expect
@@ -48,7 +48,10 @@
return 3;
}
static method foo() → asy::Future<self::X*>* async {
- return new self::X::•(let final self::Y* #t1 = new self::Y::•() in let final void #t2 = #t1.{self::Y::f}(await self::f1()) in let final void #t3 = #t1.{self::Y::f}(self::f2()) in #t1, await self::f3());
+ return new self::X::•(let final self::Y* #t1 = new self::Y::•() in block {
+ #t1.{self::Y::f}(await self::f1());
+ #t1.{self::Y::f}(self::f2());
+ } =>#t1, await self::f3());
}
static method main() → asy::Future<void>* async {
core::print(await self::foo());
diff --git a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
index dfedd80..d58c87d 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
@@ -105,16 +105,19 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ dynamic :async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
final self::Y* #t1 = new self::Y::•();
[yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
- final void #t3 = #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object*>*>(:result));
- final void #t4 = #t1.{self::Y::f}(self::f2());
- [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = new self::X::•(#t1, _in::unsafeCast<core::Object*>(:result));
+ #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object*>*>(:result));
+ :async_temporary_0 = block {
+ #t1.{self::Y::f}(self::f2());
+ } =>#t1;
+ [yield] let dynamic #t3 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = new self::X::•(_in::unsafeCast<self::Y*>(:async_temporary_0), _in::unsafeCast<core::Object*>(:result));
break #L3;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -142,7 +145,7 @@
try {
#L4:
{
- [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t4 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
core::print(_in::unsafeCast<self::X*>(:result));
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/general/cascade.dart.strong.expect b/pkg/front_end/testcases/general/cascade.dart.strong.expect
index 70120f9..b2f0be3 100644
--- a/pkg/front_end/testcases/general/cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/general/cascade.dart.strong.expect
@@ -26,24 +26,40 @@
import "dart:core" as core;
static method main() → dynamic {
- core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in let final void #t2 = #t1.{core::List::add}(2) in let final void #t3 = #t1.{core::List::add}(3) in let final void #t4 = #t1.{core::List::addAll}(<core::int*>[4, 5]) in #t1;
+ core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in block {
+ #t1.{core::List::add}(2);
+ #t1.{core::List::add}(3);
+ #t1.{core::List::addAll}(<core::int*>[4, 5]);
+ } =>#t1;
core::print(list);
- let final core::List<core::int*>* #t5 = list in let final void #t6 = #t5.{core::List::add}(2) in let final void #t7 = #t5.{core::List::length} in let final void #t8 = #t5.{core::List::length} = 0 in #t5;
+ let final core::List<core::int*>* #t2 = list in block {
+ #t2.{core::List::add}(2);
+ #t2.{core::List::length};
+ #t2.{core::List::length} = 0;
+ } =>#t2;
core::print(list);
- let final core::List<core::int*>* #t9 = list in let final void #t10 = #t9.{core::List::add}(2) in let final void #t11 = #t9.{core::List::[]}(0) in let final void #t12 = #t9.{core::List::[]=}(0, 87) in #t9;
+ let final core::List<core::int*>* #t3 = list in block {
+ #t3.{core::List::add}(2);
+ #t3.{core::List::[]}(0);
+ #t3.{core::List::[]=}(0, 87);
+ } =>#t3;
core::print(list);
- list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ list = let final core::List<core::int*>* #t4 = <core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- 'List' is from 'dart:core'.
[1]
- ^" in <core::int*>[1] as{TypeError} core::int*] in let final void #t15 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
+ ^" in <core::int*>[1] as{TypeError} core::int*] in block {
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..first.last.toString()
- ^^^^".{core::Object::toString}() in let final void #t16 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:29:12: Error: The operator '[]' isn't defined for the class 'int'.
+ ^^^^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:29:12: Error: The operator '[]' isn't defined for the class 'int'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
..first[0].toString()
- ^".{core::Object::toString}() in let final void #t17 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
+ ^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..[0].last.toString();
- ^^^^".{core::Object::toString}() in #t13;
+ ^^^^".{core::Object::toString}();
+ } =>#t4;
core::print(list);
}
diff --git a/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
index 70120f9..b2f0be3 100644
--- a/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
@@ -26,24 +26,40 @@
import "dart:core" as core;
static method main() → dynamic {
- core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in let final void #t2 = #t1.{core::List::add}(2) in let final void #t3 = #t1.{core::List::add}(3) in let final void #t4 = #t1.{core::List::addAll}(<core::int*>[4, 5]) in #t1;
+ core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in block {
+ #t1.{core::List::add}(2);
+ #t1.{core::List::add}(3);
+ #t1.{core::List::addAll}(<core::int*>[4, 5]);
+ } =>#t1;
core::print(list);
- let final core::List<core::int*>* #t5 = list in let final void #t6 = #t5.{core::List::add}(2) in let final void #t7 = #t5.{core::List::length} in let final void #t8 = #t5.{core::List::length} = 0 in #t5;
+ let final core::List<core::int*>* #t2 = list in block {
+ #t2.{core::List::add}(2);
+ #t2.{core::List::length};
+ #t2.{core::List::length} = 0;
+ } =>#t2;
core::print(list);
- let final core::List<core::int*>* #t9 = list in let final void #t10 = #t9.{core::List::add}(2) in let final void #t11 = #t9.{core::List::[]}(0) in let final void #t12 = #t9.{core::List::[]=}(0, 87) in #t9;
+ let final core::List<core::int*>* #t3 = list in block {
+ #t3.{core::List::add}(2);
+ #t3.{core::List::[]}(0);
+ #t3.{core::List::[]=}(0, 87);
+ } =>#t3;
core::print(list);
- list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ list = let final core::List<core::int*>* #t4 = <core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- 'List' is from 'dart:core'.
[1]
- ^" in <core::int*>[1] as{TypeError} core::int*] in let final void #t15 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
+ ^" in <core::int*>[1] as{TypeError} core::int*] in block {
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..first.last.toString()
- ^^^^".{core::Object::toString}() in let final void #t16 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:29:12: Error: The operator '[]' isn't defined for the class 'int'.
+ ^^^^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:29:12: Error: The operator '[]' isn't defined for the class 'int'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
..first[0].toString()
- ^".{core::Object::toString}() in let final void #t17 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
+ ^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..[0].last.toString();
- ^^^^".{core::Object::toString}() in #t13;
+ ^^^^".{core::Object::toString}();
+ } =>#t4;
core::print(list);
}
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.expect b/pkg/front_end/testcases/general/expressions.dart.strong.expect
index 3a13247..bc2f8d2 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.expect
@@ -74,7 +74,9 @@
});
core::print(core::int*.{core::Object::toString}());
core::print(core::int*);
- core::print(let final core::Type* #t5 = core::int* in let final void #t6 = #t5.{core::Object::toString}() in #t5);
+ core::print(let final core::Type* #t5 = core::int* in block {
+ #t5.{core::Object::toString}();
+ } =>#t5);
try {
core::print(invalid-expression "pkg/front_end/testcases/general/expressions.dart:74:16: Error: Method not found: 'int.toString'.
print(int?.toString());
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
index 2f75ab9..ff7bf3c 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
@@ -74,7 +74,9 @@
});
core::print(core::int*.{core::Object::toString}());
core::print(core::int*);
- core::print(let final core::Type* #t5 = core::int* in let final void #t6 = #t5.{core::Object::toString}() in #t5);
+ core::print(let final core::Type* #t5 = core::int* in block {
+ #t5.{core::Object::toString}();
+ } =>#t5);
try {
core::print(invalid-expression "pkg/front_end/testcases/general/expressions.dart:74:16: Error: Method not found: 'int.toString'.
print(int?.toString());
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.strong.expect b/pkg/front_end/testcases/general/ffi_sample.dart.strong.expect
index 4205663..e87b8a1 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.strong.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.strong.expect
@@ -14,7 +14,11 @@
field core::double* y = null;
field ffi::Pointer<self::Coordinate*>* next = null;
static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ #t1.{self::Coordinate::x} = x;
+ #t1.{self::Coordinate::y} = y;
+ #t1.{self::Coordinate::next} = next;
+ } =>#t1;
}
abstract member-signature get _addressOf() → ffi::Pointer<ffi::Struct*>*;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect b/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
index 241578e..4998dd8 100644
--- a/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.strong.transformed.expect
@@ -16,7 +16,11 @@
: super ffi::Struct::_fromPointer(#pointer)
;
static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ #t1.{self::Coordinate::x} = x;
+ #t1.{self::Coordinate::y} = y;
+ #t1.{self::Coordinate::next} = next;
+ } =>#t1;
}
abstract member-signature get _addressOf() → ffi::Pointer<ffi::Struct*>*;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.expect
index e93b141..a7e9a38 100644
--- a/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.expect
@@ -21,5 +21,7 @@
static method main() → dynamic {
self::Class* a;
self::Class* b = new self::Class::•();
- let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in let final void #t3 = #t1.{self::Class::method}() in #t1;
+ let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in block {
+ #t1.{self::Class::method}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.transformed.expect
index e93b141..a7e9a38 100644
--- a/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.strong.transformed.expect
@@ -21,5 +21,7 @@
static method main() → dynamic {
self::Class* a;
self::Class* b = new self::Class::•();
- let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in let final void #t3 = #t1.{self::Class::method}() in #t1;
+ let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in block {
+ #t1.{self::Class::method}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.strong.expect b/pkg/front_end/testcases/general/native_as_name.dart.strong.expect
index 67f9f49..0712c51 100644
--- a/pkg/front_end/testcases/general/native_as_name.dart.strong.expect
+++ b/pkg/front_end/testcases/general/native_as_name.dart.strong.expect
@@ -81,7 +81,9 @@
core::print(new self::W::•().{self::W::native});
core::print(new self::X::•().{self::X::native}());
core::print(new self::Y2::•().{self::Y2::native});
- core::print((let final self::Z* #t1 = new self::Z::•() in let final void #t2 = #t1.{self::Z::native} = "setter" in #t1).{self::Z::f});
+ core::print((let final self::Z* #t1 = new self::Z::•() in block {
+ #t1.{self::Z::native} = "setter";
+ } =>#t1).{self::Z::f});
}
constants {
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.strong.transformed.expect b/pkg/front_end/testcases/general/native_as_name.dart.strong.transformed.expect
index 67f9f49..0712c51 100644
--- a/pkg/front_end/testcases/general/native_as_name.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/native_as_name.dart.strong.transformed.expect
@@ -81,7 +81,9 @@
core::print(new self::W::•().{self::W::native});
core::print(new self::X::•().{self::X::native}());
core::print(new self::Y2::•().{self::Y2::native});
- core::print((let final self::Z* #t1 = new self::Z::•() in let final void #t2 = #t1.{self::Z::native} = "setter" in #t1).{self::Z::f});
+ core::print((let final self::Z* #t1 = new self::Z::•() in block {
+ #t1.{self::Z::native} = "setter";
+ } =>#t1).{self::Z::f});
}
constants {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.expect
index ee50ed9..33c1f7c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.expect
@@ -10,7 +10,9 @@
: super core::Object::•()
;
method m() → asy::Future<core::List<core::int*>*>* async
- return let final core::List<core::int*>* #t1 = <core::int*>[] in let final void #t2 = #t1.{core::List::add}(await this.{self::C::_m}()) in #t1;
+ return let final core::List<core::int*>* #t1 = <core::int*>[] in block {
+ #t1.{core::List::add}(await this.{self::C::_m}());
+ } =>#t1;
method _m() → asy::Future<core::int*>* async
return 42;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
index da55c50..0bb1652 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
@@ -25,7 +25,8 @@
{
final core::List<core::int*>* #t1 = <core::int*>[];
[yield] let dynamic #t2 = asy::_awaitHelper(this.{self::C::_m}(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = let final void #t3 = #t1.{core::List::add}(_in::unsafeCast<core::int*>(:result)) in #t1;
+ #t1.{core::List::add}(_in::unsafeCast<core::int*>(:result));
+ :return_value = block {} =>#t1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -91,7 +92,7 @@
try {
#L3:
{
- [yield] let dynamic #t4 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t3 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
self::expect(42, _in::unsafeCast<core::List<core::int*>*>(:result).{core::Iterable::first});
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.expect
index 8653700..2083c84 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.expect
@@ -48,7 +48,10 @@
return 3;
}
static method foo() → asy::Future<self::X*>* async {
- return new self::X::•(let final self::Y* #t1 = new self::Y::•() in let final void #t2 = #t1.{self::Y::f}(await self::f1()) in let final void #t3 = #t1.{self::Y::f}(self::f2()) in #t1, await self::f3());
+ return new self::X::•(let final self::Y* #t1 = new self::Y::•() in block {
+ #t1.{self::Y::f}(await self::f1());
+ #t1.{self::Y::f}(self::f2());
+ } =>#t1, await self::f3());
}
static method main() → asy::Future<void>* async {
core::print(await self::foo());
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
index dfedd80..d58c87d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
@@ -105,16 +105,19 @@
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ dynamic :async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
final self::Y* #t1 = new self::Y::•();
[yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
- final void #t3 = #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object*>*>(:result));
- final void #t4 = #t1.{self::Y::f}(self::f2());
- [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = new self::X::•(#t1, _in::unsafeCast<core::Object*>(:result));
+ #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object*>*>(:result));
+ :async_temporary_0 = block {
+ #t1.{self::Y::f}(self::f2());
+ } =>#t1;
+ [yield] let dynamic #t3 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = new self::X::•(_in::unsafeCast<self::Y*>(:async_temporary_0), _in::unsafeCast<core::Object*>(:result));
break #L3;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -142,7 +145,7 @@
try {
#L4:
{
- [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t4 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
core::print(_in::unsafeCast<self::X*>(:result));
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.expect
index d0a33ce..8361133 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.expect
@@ -26,24 +26,40 @@
import "dart:core" as core;
static method main() → dynamic {
- core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in let final void #t2 = #t1.{core::List::add}(2) in let final void #t3 = #t1.{core::List::add}(3) in let final void #t4 = #t1.{core::List::addAll}(<core::int*>[4, 5]) in #t1;
+ core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in block {
+ #t1.{core::List::add}(2);
+ #t1.{core::List::add}(3);
+ #t1.{core::List::addAll}(<core::int*>[4, 5]);
+ } =>#t1;
core::print(list);
- let final core::List<core::int*>* #t5 = list in let final void #t6 = #t5.{core::List::add}(2) in let final void #t7 = #t5.{core::List::length} in let final void #t8 = #t5.{core::List::length} = 0 in #t5;
+ let final core::List<core::int*>* #t2 = list in block {
+ #t2.{core::List::add}(2);
+ #t2.{core::List::length};
+ #t2.{core::List::length} = 0;
+ } =>#t2;
core::print(list);
- let final core::List<core::int*>* #t9 = list in let final void #t10 = #t9.{core::List::add}(2) in let final void #t11 = #t9.{core::List::[]}(0) in let final void #t12 = #t9.{core::List::[]=}(0, 87) in #t9;
+ let final core::List<core::int*>* #t3 = list in block {
+ #t3.{core::List::add}(2);
+ #t3.{core::List::[]}(0);
+ #t3.{core::List::[]=}(0, 87);
+ } =>#t3;
core::print(list);
- list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:28:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ list = let final core::List<core::int*>* #t4 = <core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:28:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- 'List' is from 'dart:core'.
[1]
- ^" in <core::int*>[1] as{TypeError} core::int*] in let final void #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:30:13: Error: The getter 'last' isn't defined for the class 'int'.
+ ^" in <core::int*>[1] as{TypeError} core::int*] in block {
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:30:13: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..first.last.toString()
- ^^^^".{core::Object::toString}() in let final void #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:31:12: Error: The operator '[]' isn't defined for the class 'int'.
+ ^^^^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:31:12: Error: The operator '[]' isn't defined for the class 'int'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
..first[0].toString()
- ^".{core::Object::toString}() in let final void #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:32:11: Error: The getter 'last' isn't defined for the class 'int'.
+ ^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:32:11: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..[0].last.toString();
- ^^^^".{core::Object::toString}() in #t13;
+ ^^^^".{core::Object::toString}();
+ } =>#t4;
core::print(list);
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.transformed.expect
index d0a33ce..8361133 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.weak.transformed.expect
@@ -26,24 +26,40 @@
import "dart:core" as core;
static method main() → dynamic {
- core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in let final void #t2 = #t1.{core::List::add}(2) in let final void #t3 = #t1.{core::List::add}(3) in let final void #t4 = #t1.{core::List::addAll}(<core::int*>[4, 5]) in #t1;
+ core::List<core::int*>* list = let final core::List<core::int*>* #t1 = <core::int*>[1] in block {
+ #t1.{core::List::add}(2);
+ #t1.{core::List::add}(3);
+ #t1.{core::List::addAll}(<core::int*>[4, 5]);
+ } =>#t1;
core::print(list);
- let final core::List<core::int*>* #t5 = list in let final void #t6 = #t5.{core::List::add}(2) in let final void #t7 = #t5.{core::List::length} in let final void #t8 = #t5.{core::List::length} = 0 in #t5;
+ let final core::List<core::int*>* #t2 = list in block {
+ #t2.{core::List::add}(2);
+ #t2.{core::List::length};
+ #t2.{core::List::length} = 0;
+ } =>#t2;
core::print(list);
- let final core::List<core::int*>* #t9 = list in let final void #t10 = #t9.{core::List::add}(2) in let final void #t11 = #t9.{core::List::[]}(0) in let final void #t12 = #t9.{core::List::[]=}(0, 87) in #t9;
+ let final core::List<core::int*>* #t3 = list in block {
+ #t3.{core::List::add}(2);
+ #t3.{core::List::[]}(0);
+ #t3.{core::List::[]=}(0, 87);
+ } =>#t3;
core::print(list);
- list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:28:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ list = let final core::List<core::int*>* #t4 = <core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:28:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
- 'List' is from 'dart:core'.
[1]
- ^" in <core::int*>[1] as{TypeError} core::int*] in let final void #t15 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:30:13: Error: The getter 'last' isn't defined for the class 'int'.
+ ^" in <core::int*>[1] as{TypeError} core::int*] in block {
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:30:13: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..first.last.toString()
- ^^^^".{core::Object::toString}() in let final void #t16 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:31:12: Error: The operator '[]' isn't defined for the class 'int'.
+ ^^^^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:31:12: Error: The operator '[]' isn't defined for the class 'int'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
..first[0].toString()
- ^".{core::Object::toString}() in let final void #t17 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:32:11: Error: The getter 'last' isn't defined for the class 'int'.
+ ^".{core::Object::toString}();
+ invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart:32:11: Error: The getter 'last' isn't defined for the class 'int'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
..[0].last.toString();
- ^^^^".{core::Object::toString}() in #t13;
+ ^^^^".{core::Object::toString}();
+ } =>#t4;
core::print(list);
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.expect
index 640571c..5c1a339 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.expect
@@ -74,7 +74,9 @@
});
core::print(core::int*.{core::Object::toString}());
core::print(core::int*);
- core::print(let final core::Type* #t5 = core::int* in let final void #t6 = #t5.{core::Object::toString}() in #t5);
+ core::print(let final core::Type* #t5 = core::int* in block {
+ #t5.{core::Object::toString}();
+ } =>#t5);
try {
core::print(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart:76:16: Error: Method not found: 'int.toString'.
print(int?.toString());
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.transformed.expect
index b65b78c..7e9b65e 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.weak.transformed.expect
@@ -74,7 +74,9 @@
});
core::print(core::int*.{core::Object::toString}());
core::print(core::int*);
- core::print(let final core::Type* #t5 = core::int* in let final void #t6 = #t5.{core::Object::toString}() in #t5);
+ core::print(let final core::Type* #t5 = core::int* in block {
+ #t5.{core::Object::toString}();
+ } =>#t5);
try {
core::print(invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart:76:16: Error: Method not found: 'int.toString'.
print(int?.toString());
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
index 4205663..e87b8a1 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.expect
@@ -14,7 +14,11 @@
field core::double* y = null;
field ffi::Pointer<self::Coordinate*>* next = null;
static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ #t1.{self::Coordinate::x} = x;
+ #t1.{self::Coordinate::y} = y;
+ #t1.{self::Coordinate::next} = next;
+ } =>#t1;
}
abstract member-signature get _addressOf() → ffi::Pointer<ffi::Struct*>*;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
index 241578e..4998dd8 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.weak.transformed.expect
@@ -16,7 +16,11 @@
: super ffi::Struct::_fromPointer(#pointer)
;
static factory allocate(core::double* x, core::double* y, ffi::Pointer<self::Coordinate*>* next) → self::Coordinate* {
- return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in let final void #t2 = #t1.{self::Coordinate::x} = x in let final void #t3 = #t1.{self::Coordinate::y} = y in let final void #t4 = #t1.{self::Coordinate::next} = next in #t1;
+ return let final self::Coordinate* #t1 = ffi::StructPointer|get#ref<self::Coordinate*>(all::allocate<self::Coordinate*>()) in block {
+ #t1.{self::Coordinate::x} = x;
+ #t1.{self::Coordinate::y} = y;
+ #t1.{self::Coordinate::next} = next;
+ } =>#t1;
}
abstract member-signature get _addressOf() → ffi::Pointer<ffi::Struct*>*;
abstract member-signature get _identityHashCode() → core::int*;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.expect
index e93b141..a7e9a38 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.expect
@@ -21,5 +21,7 @@
static method main() → dynamic {
self::Class* a;
self::Class* b = new self::Class::•();
- let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in let final void #t3 = #t1.{self::Class::method}() in #t1;
+ let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in block {
+ #t1.{self::Class::method}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.transformed.expect
index e93b141..a7e9a38 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.weak.transformed.expect
@@ -21,5 +21,7 @@
static method main() → dynamic {
self::Class* a;
self::Class* b = new self::Class::•();
- let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in let final void #t3 = #t1.{self::Class::method}() in #t1;
+ let final self::Class* #t1 = let final self::Class* #t2 = a in #t2.{self::Class::==}(null) ?{self::Class*} b : #t2 in block {
+ #t1.{self::Class::method}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.expect
index 67f9f49..0712c51 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.expect
@@ -81,7 +81,9 @@
core::print(new self::W::•().{self::W::native});
core::print(new self::X::•().{self::X::native}());
core::print(new self::Y2::•().{self::Y2::native});
- core::print((let final self::Z* #t1 = new self::Z::•() in let final void #t2 = #t1.{self::Z::native} = "setter" in #t1).{self::Z::f});
+ core::print((let final self::Z* #t1 = new self::Z::•() in block {
+ #t1.{self::Z::native} = "setter";
+ } =>#t1).{self::Z::f});
}
constants {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.transformed.expect
index 67f9f49..0712c51 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.weak.transformed.expect
@@ -81,7 +81,9 @@
core::print(new self::W::•().{self::W::native});
core::print(new self::X::•().{self::X::native}());
core::print(new self::Y2::•().{self::Y2::native});
- core::print((let final self::Z* #t1 = new self::Z::•() in let final void #t2 = #t1.{self::Z::native} = "setter" in #t1).{self::Z::f});
+ core::print((let final self::Z* #t1 = new self::Z::•() in block {
+ #t1.{self::Z::native} = "setter";
+ } =>#t1).{self::Z::f});
}
constants {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
index 2e0067b..047b515 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.1.expect
@@ -117,7 +117,9 @@
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String {
if(this.{dart.core::List::length}.{dart.core::num::==}(0))
return "";
- dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in let final void #t2 = #t1.{dart.core::StringBuffer::writeAll}(this, separator) in #t1;
+ dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block {
+ #t1.{dart.core::StringBuffer::writeAll}(this, separator);
+ } =>#t1;
return buffer.{dart.core::StringBuffer::toString}();
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*>
@@ -239,7 +241,7 @@
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%>
return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void {
- dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t3 = compare in #t3.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t3{(dart.core::int*, dart.core::int*) → dart.core::int});
+ dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int});
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void {
random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null;
@@ -259,22 +261,22 @@
}
operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
return block {
- final dart.core::List<dart.core::int*> #t4 = <dart.core::int*>[];
+ final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[];
{
dart.core::Iterator<dart.core::int*> :sync-for-iterator = this.{dart.core::Iterable::iterator};
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
- final dart.core::int* #t5 = :sync-for-iterator.{dart.core::Iterator::current};
- #t4.{dart.core::List::add}(#t5);
+ final dart.core::int* #t4 = :sync-for-iterator.{dart.core::Iterator::current};
+ #t3.{dart.core::List::add}(#t4);
}
}
{
dart.core::Iterator<dart.core::int*> :sync-for-iterator = other.{dart.core::Iterable::iterator};
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
- final dart.core::int* #t6 = :sync-for-iterator.{dart.core::Iterator::current};
- #t4.{dart.core::List::add}(#t6);
+ final dart.core::int* #t5 = :sync-for-iterator.{dart.core::Iterator::current};
+ #t3.{dart.core::List::add}(#t5);
}
}
- } =>#t4;
+ } =>#t3;
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
dart.core::int listLength = this.{dart.core::List::length};
end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null;
@@ -294,7 +296,7 @@
}
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
- dart.core::int* value = let dart.core::int? #t7 = fill in #t7.==(null) ?{dart.core::int*} #t7 : #t7{dart.core::int*};
+ dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value);
@@ -473,7 +475,7 @@
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
{
- this.{dart.core::List::[]=}(let final dart.core::int #t8 = index in let final dart.core::int #t9 = index = #t8.{dart.core::num::+}(1) in #t8, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
}
}
}
@@ -521,7 +523,7 @@
return this.{dart.core::List::[]}(0);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
- this.{dart.core::List::[]=}(let final dart.core::int #t10 = this.{dart.core::List::length} in let final dart.core::int #t11 = this.{dart.core::List::length} = #t10.{dart.core::num::+}(1) in #t10, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
index 2e0067b..047b515 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_22.yaml.world.2.expect
@@ -117,7 +117,9 @@
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String {
if(this.{dart.core::List::length}.{dart.core::num::==}(0))
return "";
- dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in let final void #t2 = #t1.{dart.core::StringBuffer::writeAll}(this, separator) in #t1;
+ dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block {
+ #t1.{dart.core::StringBuffer::writeAll}(this, separator);
+ } =>#t1;
return buffer.{dart.core::StringBuffer::toString}();
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*>
@@ -239,7 +241,7 @@
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%>
return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void {
- dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t3 = compare in #t3.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t3{(dart.core::int*, dart.core::int*) → dart.core::int});
+ dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int});
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void {
random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null;
@@ -259,22 +261,22 @@
}
operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
return block {
- final dart.core::List<dart.core::int*> #t4 = <dart.core::int*>[];
+ final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[];
{
dart.core::Iterator<dart.core::int*> :sync-for-iterator = this.{dart.core::Iterable::iterator};
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
- final dart.core::int* #t5 = :sync-for-iterator.{dart.core::Iterator::current};
- #t4.{dart.core::List::add}(#t5);
+ final dart.core::int* #t4 = :sync-for-iterator.{dart.core::Iterator::current};
+ #t3.{dart.core::List::add}(#t4);
}
}
{
dart.core::Iterator<dart.core::int*> :sync-for-iterator = other.{dart.core::Iterable::iterator};
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
- final dart.core::int* #t6 = :sync-for-iterator.{dart.core::Iterator::current};
- #t4.{dart.core::List::add}(#t6);
+ final dart.core::int* #t5 = :sync-for-iterator.{dart.core::Iterator::current};
+ #t3.{dart.core::List::add}(#t5);
}
}
- } =>#t4;
+ } =>#t3;
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
dart.core::int listLength = this.{dart.core::List::length};
end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null;
@@ -294,7 +296,7 @@
}
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
- dart.core::int* value = let dart.core::int? #t7 = fill in #t7.==(null) ?{dart.core::int*} #t7 : #t7{dart.core::int*};
+ dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value);
@@ -473,7 +475,7 @@
for (; :sync-for-iterator.{dart.core::Iterator::moveNext}(); ) {
dart.core::int* element = :sync-for-iterator.{dart.core::Iterator::current};
{
- this.{dart.core::List::[]=}(let final dart.core::int #t8 = index in let final dart.core::int #t9 = index = #t8.{dart.core::num::+}(1) in #t8, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t7 = index in let final dart.core::int #t8 = index = #t7.{dart.core::num::+}(1) in #t7, element);
}
}
}
@@ -521,7 +523,7 @@
return this.{dart.core::List::[]}(0);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
- this.{dart.core::List::[]=}(let final dart.core::int #t10 = this.{dart.core::List::length} in let final dart.core::int #t11 = this.{dart.core::List::length} = #t10.{dart.core::num::+}(1) in #t10, element);
+ this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
}
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0;
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.1.expect
index c1312ba..317d3e2 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.1.expect
@@ -23,8 +23,8 @@
;
get field5() → dart.core::int? {
if(!this.{main::C::_#C#field5#isSet}) {
- this.{main::C::_#C#field5#isSet} = true;
this.{main::C::_#C#field5} = 42;
+ this.{main::C::_#C#field5#isSet} = true;
}
return this.{main::C::_#C#field5};
}
@@ -43,8 +43,8 @@
final dart.core::int? #t3 = 42;
if(this.{main::C::_#C#field7#isSet})
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field7' has been assigned during initialization.");
- this.{main::C::_#C#field7#isSet} = true;
this.{main::C::_#C#field7} = #t3;
+ this.{main::C::_#C#field7#isSet} = true;
}
return this.{main::C::_#C#field7};
}
@@ -59,8 +59,8 @@
}
static get field9() → dart.core::int? {
if(!main::C::_#field9#isSet) {
- main::C::_#field9#isSet = true;
main::C::_#field9 = 42;
+ main::C::_#field9#isSet = true;
}
return main::C::_#field9;
}
@@ -79,8 +79,8 @@
final dart.core::int? #t7 = 42;
if(main::C::_#field11#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field11' has been assigned during initialization.");
- main::C::_#field11#isSet = true;
main::C::_#field11 = #t7;
+ main::C::_#field11#isSet = true;
}
return main::C::_#field11;
}
@@ -104,8 +104,8 @@
static field dart.core::bool _#field4#isSet = false;
static get field1() → dart.core::int? {
if(!main::_#field1#isSet) {
- main::_#field1#isSet = true;
main::_#field1 = 42;
+ main::_#field1#isSet = true;
}
return main::_#field1;
}
@@ -124,8 +124,8 @@
final dart.core::int? #t11 = 42;
if(main::_#field3#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field3' has been assigned during initialization.");
- main::_#field3#isSet = true;
main::_#field3 = #t11;
+ main::_#field3#isSet = true;
}
return main::_#field3;
}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.2.expect
index fcb2736..4e90b8f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_29.yaml.world.2.expect
@@ -23,8 +23,8 @@
;
get field5() → dart.core::int? {
if(!this.{main::C::_#C#field5#isSet}) {
- this.{main::C::_#C#field5#isSet} = true;
this.{main::C::_#C#field5} = 42;
+ this.{main::C::_#C#field5#isSet} = true;
}
return this.{main::C::_#C#field5};
}
@@ -43,8 +43,8 @@
final dart.core::int? #t3 = 42;
if(this.{main::C::_#C#field7#isSet})
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field7' has been assigned during initialization.");
- this.{main::C::_#C#field7#isSet} = true;
this.{main::C::_#C#field7} = #t3;
+ this.{main::C::_#C#field7#isSet} = true;
}
return this.{main::C::_#C#field7};
}
@@ -59,8 +59,8 @@
}
static get field9() → dart.core::int? {
if(!main::C::_#field9#isSet) {
- main::C::_#field9#isSet = true;
main::C::_#field9 = 42;
+ main::C::_#field9#isSet = true;
}
return main::C::_#field9;
}
@@ -79,8 +79,8 @@
final dart.core::int? #t7 = 42;
if(main::C::_#field11#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field11' has been assigned during initialization.");
- main::C::_#field11#isSet = true;
main::C::_#field11 = #t7;
+ main::C::_#field11#isSet = true;
}
return main::C::_#field11;
}
@@ -104,8 +104,8 @@
static field dart.core::bool _#field4#isSet = false;
static get field1() → dart.core::int? {
if(!main::_#field1#isSet) {
- main::_#field1#isSet = true;
main::_#field1 = 42;
+ main::_#field1#isSet = true;
}
return main::_#field1;
}
@@ -124,8 +124,8 @@
final dart.core::int? #t11 = 42;
if(main::_#field3#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field3' has been assigned during initialization.");
- main::_#field3#isSet = true;
main::_#field3 = #t11;
+ main::_#field3#isSet = true;
}
return main::_#field3;
}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.1.expect
index 0bb5760..a34308e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.1.expect
@@ -41,8 +41,8 @@
static field dart.core::bool _#_extension#0|field8#isSet = false;
static get field1() → dart.core::int? {
if(!main::_#field1#isSet) {
- main::_#field1#isSet = true;
main::_#field1 = 42;
+ main::_#field1#isSet = true;
}
return main::_#field1;
}
@@ -61,8 +61,8 @@
final dart.core::int? #t3 = 42;
if(main::_#field3#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field3' has been assigned during initialization.");
- main::_#field3#isSet = true;
main::_#field3 = #t3;
+ main::_#field3#isSet = true;
}
return main::_#field3;
}
@@ -77,8 +77,8 @@
}
static get _extension#0|field5() → dart.core::int? {
if(!main::_#_extension#0|field5#isSet) {
- main::_#_extension#0|field5#isSet = true;
main::_#_extension#0|field5 = 42;
+ main::_#_extension#0|field5#isSet = true;
}
return main::_#_extension#0|field5;
}
@@ -97,8 +97,8 @@
final dart.core::int? #t7 = 42;
if(main::_#_extension#0|field7#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field7' has been assigned during initialization.");
- main::_#_extension#0|field7#isSet = true;
main::_#_extension#0|field7 = #t7;
+ main::_#_extension#0|field7#isSet = true;
}
return main::_#_extension#0|field7;
}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.2.expect
index fdf6f59..246b57d 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_31.yaml.world.2.expect
@@ -41,8 +41,8 @@
static field dart.core::bool _#_extension#0|field8#isSet = false;
static get field1() → dart.core::int? {
if(!main::_#field1#isSet) {
- main::_#field1#isSet = true;
main::_#field1 = 42;
+ main::_#field1#isSet = true;
}
return main::_#field1;
}
@@ -61,8 +61,8 @@
final dart.core::int? #t3 = 42;
if(main::_#field3#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field3' has been assigned during initialization.");
- main::_#field3#isSet = true;
main::_#field3 = #t3;
+ main::_#field3#isSet = true;
}
return main::_#field3;
}
@@ -77,8 +77,8 @@
}
static get _extension#0|field5() → dart.core::int? {
if(!main::_#_extension#0|field5#isSet) {
- main::_#_extension#0|field5#isSet = true;
main::_#_extension#0|field5 = 42;
+ main::_#_extension#0|field5#isSet = true;
}
return main::_#_extension#0|field5;
}
@@ -97,8 +97,8 @@
final dart.core::int? #t7 = 42;
if(main::_#_extension#0|field7#isSet)
throw new dart._internal::LateInitializationErrorImpl::•("Field 'field7' has been assigned during initialization.");
- main::_#_extension#0|field7#isSet = true;
main::_#_extension#0|field7 = #t7;
+ main::_#_extension#0|field7#isSet = true;
}
return main::_#_extension#0|field7;
}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
index 66440f82..30b6824 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
@@ -30,9 +30,11 @@
core::num* y;
self::C<core::int*>* c_int = new self::C::•<core::int*>(y as{TypeError} core::int*);
self::C<core::num*>* c_num = new self::C::•<core::num*>(123);
- self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final void #t2 = #t1.{self::C::t} = 1.0 in #t1;
+ self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in block {
+ #t1.{self::C::t} = 1.0;
+ } =>#t1;
self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
- x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x.{self::C::t} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
^" in "hello" as{TypeError} core::int*;
}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
index 66440f82..30b6824 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -30,9 +30,11 @@
core::num* y;
self::C<core::int*>* c_int = new self::C::•<core::int*>(y as{TypeError} core::int*);
self::C<core::num*>* c_num = new self::C::•<core::num*>(123);
- self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final void #t2 = #t1.{self::C::t} = 1.0 in #t1;
+ self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in block {
+ #t1.{self::C::t} = 1.0;
+ } =>#t1;
self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
- x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+ x.{self::C::t} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:55: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
x. /*@target=C.t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
^" in "hello" as{TypeError} core::int*;
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.expect
index e656b2f..c9abbef 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.expect
@@ -33,6 +33,8 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
-static field self::A* t1 = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::b} = new self::B::•<core::int*>(1) in #t1;
+static field self::A* t1 = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::b} = new self::B::•<core::int*>(1);
+} =>#t1;
static field core::List<self::B<core::int*>*>* t2 = <self::B<core::int*>*>[new self::B::•<core::int*>(2)];
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect
index e656b2f..c9abbef 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect
@@ -33,6 +33,8 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
-static field self::A* t1 = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::b} = new self::B::•<core::int*>(1) in #t1;
+static field self::A* t1 = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::b} = new self::B::•<core::int*>(1);
+} =>#t1;
static field core::List<self::B<core::int*>*>* t2 = <self::B<core::int*>*>[new self::B::•<core::int*>(2)];
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
index e77093c..b5bef3b 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
@@ -109,7 +109,9 @@
^"];
static field core::List<dynamic>* c2 = #C1;
static field core::Map<dynamic, dynamic>* d = <dynamic, dynamic>{"a": "b"};
-static field self::A* e = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::x} = 3 in #t1;
+static field self::A* e = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::x} = 3;
+} =>#t1;
static field core::int* f = 2.{core::num::+}(3);
static field core::int* g = 3.{core::int::unary-}();
static field self::B* h = new self::A::•().{self::A::+}(3);
@@ -120,59 +122,59 @@
^";
static field self::B* j = null as self::B*;
static method test1() → dynamic {
- self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+ self::a = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
^" in "hi" as{TypeError} self::A*;
self::a = new self::B::•(3);
- self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
+ self::b = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
^" in "hi" as{TypeError} self::B*;
self::b = new self::B::•(3);
self::c1 = <dynamic>[];
- self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ self::c1 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
- ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
+ ^" in (let final core::Set<dynamic>* #t5 = col::LinkedHashSet::•<dynamic>() in #t5) as{TypeError} core::List<dynamic>*;
self::c2 = <dynamic>[];
- self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ self::c2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
- ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
+ ^" in (let final core::Set<dynamic>* #t7 = col::LinkedHashSet::•<dynamic>() in #t7) as{TypeError} core::List<dynamic>*;
self::d = <dynamic, dynamic>{};
- self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+ self::d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
- 'Map' is from 'dart:core'.
d = /*error:INVALID_ASSIGNMENT*/ 3;
^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
self::e = new self::A::•();
- self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+ self::e = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
- 'Map' is from 'dart:core'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
^" in <dynamic, dynamic>{} as{TypeError} self::A*;
self::f = 3;
- self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::f = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
f = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
self::g = 1;
- self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::g = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
g = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
- self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::h = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
h = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} self::B*;
self::h = new self::B::•("b");
self::i = false;
self::j = new self::B::•("b");
- self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
j = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} self::B*;
- self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
index 7dc9b4c..7974856 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
@@ -109,7 +109,9 @@
^"];
static field core::List<dynamic>* c2 = #C1;
static field core::Map<dynamic, dynamic>* d = <dynamic, dynamic>{"a": "b"};
-static field self::A* e = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::x} = 3 in #t1;
+static field self::A* e = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::x} = 3;
+} =>#t1;
static field core::int* f = 2.{core::num::+}(3);
static field core::int* g = 3.{core::int::unary-}();
static field self::B* h = new self::A::•().{self::A::+}(3);
@@ -120,59 +122,59 @@
^";
static field self::B* j = null;
static method test1() → dynamic {
- self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+ self::a = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
^" in "hi" as{TypeError} self::A*;
self::a = new self::B::•(3);
- self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
+ self::b = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
^" in "hi" as{TypeError} self::B*;
self::b = new self::B::•(3);
self::c1 = <dynamic>[];
- self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ self::c1 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
- ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
+ ^" in (let final core::Set<dynamic>* #t5 = col::LinkedHashSet::•<dynamic>() in #t5) as{TypeError} core::List<dynamic>*;
self::c2 = <dynamic>[];
- self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ self::c2 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
- ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
+ ^" in (let final core::Set<dynamic>* #t7 = col::LinkedHashSet::•<dynamic>() in #t7) as{TypeError} core::List<dynamic>*;
self::d = <dynamic, dynamic>{};
- self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+ self::d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
- 'Map' is from 'dart:core'.
d = /*error:INVALID_ASSIGNMENT*/ 3;
^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
self::e = new self::A::•();
- self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+ self::e = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
- 'Map' is from 'dart:core'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
^" in <dynamic, dynamic>{} as{TypeError} self::A*;
self::f = 3;
- self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::f = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
f = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
self::g = 1;
- self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::g = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
g = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
- self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::h = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
h = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} self::B*;
self::h = new self::B::•("b");
self::i = false;
self::j = new self::B::•("b");
- self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
j = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} self::B*;
- self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.expect
index f1df00a..48d4fcb 100644
--- a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.expect
@@ -20,5 +20,9 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
-static field self::A* v = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::a} = 1 in let final void #t3 = #t1.{self::A::b}.{core::List::add}(2) in let final void #t4 = #t1.{self::A::m}() in #t1;
+static field self::A* v = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::a} = 1;
+ #t1.{self::A::b}.{core::List::add}(2);
+ #t1.{self::A::m}();
+} =>#t1;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect
index f1df00a..48d4fcb 100644
--- a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect
@@ -20,5 +20,9 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
-static field self::A* v = let final self::A* #t1 = new self::A::•() in let final void #t2 = #t1.{self::A::a} = 1 in let final void #t3 = #t1.{self::A::b}.{core::List::add}(2) in let final void #t4 = #t1.{self::A::m}() in #t1;
+static field self::A* v = let final self::A* #t1 = new self::A::•() in block {
+ #t1.{self::A::a} = 1;
+ #t1.{self::A::b}.{core::List::add}(2);
+ #t1.{self::A::m}();
+} =>#t1;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
index 759a7c9..7594fd4 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.expect
@@ -123,8 +123,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -178,8 +178,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -250,8 +250,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodDirect::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodDirect::T%};
}
@@ -305,8 +305,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodConditional::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodConditional::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
index 759a7c9..7594fd4 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.strong.transformed.expect
@@ -123,8 +123,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -178,8 +178,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -250,8 +250,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodDirect::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodDirect::T%};
}
@@ -305,8 +305,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodConditional::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodConditional::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
index 759a7c9..7594fd4 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.expect
@@ -123,8 +123,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -178,8 +178,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -250,8 +250,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodDirect::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodDirect::T%};
}
@@ -305,8 +305,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodConditional::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodConditional::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
index 759a7c9..7594fd4 100644
--- a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.weak.transformed.expect
@@ -123,8 +123,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -178,8 +178,8 @@
core::bool #local7#isSet = false;
function #local7#get() → T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{T%};
}
@@ -250,8 +250,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodDirect::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodDirect::T%};
}
@@ -305,8 +305,8 @@
core::bool #local7#isSet = false;
function #local7#get() → self::methodConditional::T% {
if(!#local7#isSet) {
- #local7#isSet = true;
local7 = value;
+ #local7#isSet = true;
}
return local7{self::methodConditional::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
index d8e7cc1..1edfa3c 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.expect
@@ -24,8 +24,8 @@
final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
if(self::Class::_#nullableStaticField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
- self::Class::_#nullableStaticField#isSet = true;
self::Class::_#nullableStaticField = #t5;
+ self::Class::_#nullableStaticField#isSet = true;
}
return self::Class::_#nullableStaticField;
}
@@ -36,8 +36,8 @@
final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
if(this.{self::Class::_#Class#nullableInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
this.{self::Class::_#Class#nullableInstanceField} = #t12;
+ this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#nullableInstanceField};
}
@@ -54,8 +54,8 @@
final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int} self::nullableTopLevelField.{core::Object::hashCode} : 0;
if(self::_#nullableTopLevelField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = #t19;
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
index d8e7cc1..1edfa3c 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.strong.transformed.expect
@@ -24,8 +24,8 @@
final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
if(self::Class::_#nullableStaticField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
- self::Class::_#nullableStaticField#isSet = true;
self::Class::_#nullableStaticField = #t5;
+ self::Class::_#nullableStaticField#isSet = true;
}
return self::Class::_#nullableStaticField;
}
@@ -36,8 +36,8 @@
final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
if(this.{self::Class::_#Class#nullableInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
this.{self::Class::_#Class#nullableInstanceField} = #t12;
+ this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#nullableInstanceField};
}
@@ -54,8 +54,8 @@
final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int} self::nullableTopLevelField.{core::Object::hashCode} : 0;
if(self::_#nullableTopLevelField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = #t19;
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
index d8e7cc1..1edfa3c 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.expect
@@ -24,8 +24,8 @@
final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
if(self::Class::_#nullableStaticField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
- self::Class::_#nullableStaticField#isSet = true;
self::Class::_#nullableStaticField = #t5;
+ self::Class::_#nullableStaticField#isSet = true;
}
return self::Class::_#nullableStaticField;
}
@@ -36,8 +36,8 @@
final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
if(this.{self::Class::_#Class#nullableInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
this.{self::Class::_#Class#nullableInstanceField} = #t12;
+ this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#nullableInstanceField};
}
@@ -54,8 +54,8 @@
final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int} self::nullableTopLevelField.{core::Object::hashCode} : 0;
if(self::_#nullableTopLevelField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = #t19;
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
index d8e7cc1..1edfa3c 100644
--- a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.weak.transformed.expect
@@ -24,8 +24,8 @@
final core::int? #t5 = (let final core::int #t6 = self::Class::nullableStaticFieldReads in let final core::int #t7 = self::Class::nullableStaticFieldReads = #t6.{core::num::+}(1) in #t6).{core::num::==}(0) ?{core::int} self::Class::nullableStaticField.{core::Object::hashCode} : 0;
if(self::Class::_#nullableStaticField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableStaticField' has been assigned during initialization.");
- self::Class::_#nullableStaticField#isSet = true;
self::Class::_#nullableStaticField = #t5;
+ self::Class::_#nullableStaticField#isSet = true;
}
return self::Class::_#nullableStaticField;
}
@@ -36,8 +36,8 @@
final core::int? #t12 = (let final core::int #t13 = this.{self::Class::nullableInstanceFieldReads} in let final core::int #t14 = this.{self::Class::nullableInstanceFieldReads} = #t13.{core::num::+}(1) in #t13).{core::num::==}(0) ?{core::int} this.{self::Class::nullableInstanceField}.{core::Object::hashCode} : 0;
if(this.{self::Class::_#Class#nullableInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'nullableInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
this.{self::Class::_#Class#nullableInstanceField} = #t12;
+ this.{self::Class::_#Class#nullableInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#nullableInstanceField};
}
@@ -54,8 +54,8 @@
final core::int? #t19 = (let final core::int #t20 = self::nullableTopLevelFieldReads in let final core::int #t21 = self::nullableTopLevelFieldReads = #t20.{core::num::+}(1) in #t20).{core::num::==}(0) ?{core::int} self::nullableTopLevelField.{core::Object::hashCode} : 0;
if(self::_#nullableTopLevelField#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'nullableTopLevelField' has been assigned during initialization.");
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = #t19;
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.expect
index a133a76..7895ba5 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.expect
@@ -19,8 +19,8 @@
;
get field() → core::int? {
if(!this.{self::Class::_#Class#field#isSet}) {
- this.{self::Class::_#Class#field#isSet} = true;
this.{self::Class::_#Class#field} = self::initField();
+ this.{self::Class::_#Class#field#isSet} = true;
}
return this.{self::Class::_#Class#field};
}
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.transformed.expect
index a133a76..7895ba5 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.strong.transformed.expect
@@ -19,8 +19,8 @@
;
get field() → core::int? {
if(!this.{self::Class::_#Class#field#isSet}) {
- this.{self::Class::_#Class#field#isSet} = true;
this.{self::Class::_#Class#field} = self::initField();
+ this.{self::Class::_#Class#field#isSet} = true;
}
return this.{self::Class::_#Class#field};
}
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.expect
index a133a76..7895ba5 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.expect
@@ -19,8 +19,8 @@
;
get field() → core::int? {
if(!this.{self::Class::_#Class#field#isSet}) {
- this.{self::Class::_#Class#field#isSet} = true;
this.{self::Class::_#Class#field} = self::initField();
+ this.{self::Class::_#Class#field#isSet} = true;
}
return this.{self::Class::_#Class#field};
}
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.transformed.expect
index a133a76..7895ba5 100644
--- a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.weak.transformed.expect
@@ -19,8 +19,8 @@
;
get field() → core::int? {
if(!this.{self::Class::_#Class#field#isSet}) {
- this.{self::Class::_#Class#field#isSet} = true;
this.{self::Class::_#Class#field} = self::initField();
+ this.{self::Class::_#Class#field#isSet} = true;
}
return this.{self::Class::_#Class#field};
}
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart b/pkg/front_end/testcases/late_lowering/issue41922.dart
new file mode 100644
index 0000000..74438c8
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool _called = false;
+
+String init(String val) {
+ if (!_called) {
+ _called = true;
+ throw new Exception();
+ }
+ return val;
+}
+
+class C {
+ static late String? s = init("lateValue");
+}
+
+main() {
+ throws(() {
+ C.s;
+ });
+ expect("lateValue", C.s);
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(void Function() f) {
+ try {
+ f();
+ } catch (_) {
+ return;
+ }
+ throw 'Expected exception';
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.outline.expect
new file mode 100644
index 0000000..636ec1c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.outline.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ static field core::String? _#s;
+ static field core::bool _#s#isSet;
+ synthetic constructor •() → self::C
+ ;
+ static get s() → core::String?;
+ static set s(core::String? #t1) → void;
+}
+static field core::bool _called;
+static method init(core::String val) → core::String
+ ;
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
+static method throws(() → void f) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.expect
new file mode 100644
index 0000000..14ecf83
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ static field core::String? _#s = null;
+ static field core::bool _#s#isSet = false;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ static get s() → core::String? {
+ if(!self::C::_#s#isSet) {
+ self::C::_#s = self::init("lateValue");
+ self::C::_#s#isSet = true;
+ }
+ return self::C::_#s;
+ }
+ static set s(core::String? #t1) → void {
+ self::C::_#s#isSet = true;
+ self::C::_#s = #t1;
+ }
+}
+static field core::bool _called = false;
+static method init(core::String val) → core::String {
+ if(!self::_called) {
+ self::_called = true;
+ throw core::Exception::•();
+ }
+ return val;
+}
+static method main() → dynamic {
+ self::throws(() → core::Null? {
+ self::C::s;
+ });
+ self::expect("lateValue", self::C::s);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → dynamic {
+ try {
+ f.call();
+ }
+ on core::Object catch(final core::Object _) {
+ return;
+ }
+ throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.transformed.expect
new file mode 100644
index 0000000..14ecf83
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ static field core::String? _#s = null;
+ static field core::bool _#s#isSet = false;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ static get s() → core::String? {
+ if(!self::C::_#s#isSet) {
+ self::C::_#s = self::init("lateValue");
+ self::C::_#s#isSet = true;
+ }
+ return self::C::_#s;
+ }
+ static set s(core::String? #t1) → void {
+ self::C::_#s#isSet = true;
+ self::C::_#s = #t1;
+ }
+}
+static field core::bool _called = false;
+static method init(core::String val) → core::String {
+ if(!self::_called) {
+ self::_called = true;
+ throw core::Exception::•();
+ }
+ return val;
+}
+static method main() → dynamic {
+ self::throws(() → core::Null? {
+ self::C::s;
+ });
+ self::expect("lateValue", self::C::s);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → dynamic {
+ try {
+ f.call();
+ }
+ on core::Object catch(final core::Object _) {
+ return;
+ }
+ throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.textual_outline.expect
new file mode 100644
index 0000000..c407de0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+bool _called = false;
+String init(String val) { }
+class C {
+ static late String;
+ operator? ( ){ }
+ s = init("lateValue");
+}
+main() { }
+expect(expected, actual) { }
+throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.expect
new file mode 100644
index 0000000..14ecf83
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ static field core::String? _#s = null;
+ static field core::bool _#s#isSet = false;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ static get s() → core::String? {
+ if(!self::C::_#s#isSet) {
+ self::C::_#s = self::init("lateValue");
+ self::C::_#s#isSet = true;
+ }
+ return self::C::_#s;
+ }
+ static set s(core::String? #t1) → void {
+ self::C::_#s#isSet = true;
+ self::C::_#s = #t1;
+ }
+}
+static field core::bool _called = false;
+static method init(core::String val) → core::String {
+ if(!self::_called) {
+ self::_called = true;
+ throw core::Exception::•();
+ }
+ return val;
+}
+static method main() → dynamic {
+ self::throws(() → core::Null? {
+ self::C::s;
+ });
+ self::expect("lateValue", self::C::s);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → dynamic {
+ try {
+ f.call();
+ }
+ on core::Object catch(final core::Object _) {
+ return;
+ }
+ throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.transformed.expect
new file mode 100644
index 0000000..14ecf83
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41922.dart.weak.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ static field core::String? _#s = null;
+ static field core::bool _#s#isSet = false;
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ static get s() → core::String? {
+ if(!self::C::_#s#isSet) {
+ self::C::_#s = self::init("lateValue");
+ self::C::_#s#isSet = true;
+ }
+ return self::C::_#s;
+ }
+ static set s(core::String? #t1) → void {
+ self::C::_#s#isSet = true;
+ self::C::_#s = #t1;
+ }
+}
+static field core::bool _called = false;
+static method init(core::String val) → core::String {
+ if(!self::_called) {
+ self::_called = true;
+ throw core::Exception::•();
+ }
+ return val;
+}
+static method main() → dynamic {
+ self::throws(() → core::Null? {
+ self::C::s;
+ });
+ self::expect("lateValue", self::C::s);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → dynamic {
+ try {
+ f.call();
+ }
+ on core::Object catch(final core::Object _) {
+ return;
+ }
+ throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.expect
index 9a2d29b..d9bfacd 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.expect
@@ -20,8 +20,8 @@
this.{self::A::_#A#nonNullableInstanceField} = #t2;
get nullableInstanceField() → core::int? {
if(!this.{self::A::_#A#nullableInstanceField#isSet}) {
- this.{self::A::_#A#nullableInstanceField#isSet} = true;
this.{self::A::_#A#nullableInstanceField} = self::method();
+ this.{self::A::_#A#nullableInstanceField#isSet} = true;
}
return this.{self::A::_#A#nullableInstanceField};
}
@@ -35,8 +35,8 @@
self::A::_#nonNullableStaticField = #t5;
static get nullableStaticField() → core::int? {
if(!self::A::_#nullableStaticField#isSet) {
- self::A::_#nullableStaticField#isSet = true;
self::A::_#nullableStaticField = self::method();
+ self::A::_#nullableStaticField#isSet = true;
}
return self::A::_#nullableStaticField;
}
@@ -68,8 +68,8 @@
self::_#nonNullableTopLevelField = #t8;
static get nullableTopLevelField() → core::int? {
if(!self::_#nullableTopLevelField#isSet) {
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = self::method();
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.transformed.expect
index 9a2d29b..d9bfacd 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.strong.transformed.expect
@@ -20,8 +20,8 @@
this.{self::A::_#A#nonNullableInstanceField} = #t2;
get nullableInstanceField() → core::int? {
if(!this.{self::A::_#A#nullableInstanceField#isSet}) {
- this.{self::A::_#A#nullableInstanceField#isSet} = true;
this.{self::A::_#A#nullableInstanceField} = self::method();
+ this.{self::A::_#A#nullableInstanceField#isSet} = true;
}
return this.{self::A::_#A#nullableInstanceField};
}
@@ -35,8 +35,8 @@
self::A::_#nonNullableStaticField = #t5;
static get nullableStaticField() → core::int? {
if(!self::A::_#nullableStaticField#isSet) {
- self::A::_#nullableStaticField#isSet = true;
self::A::_#nullableStaticField = self::method();
+ self::A::_#nullableStaticField#isSet = true;
}
return self::A::_#nullableStaticField;
}
@@ -68,8 +68,8 @@
self::_#nonNullableTopLevelField = #t8;
static get nullableTopLevelField() → core::int? {
if(!self::_#nullableTopLevelField#isSet) {
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = self::method();
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.expect
index 9a2d29b..d9bfacd 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.expect
@@ -20,8 +20,8 @@
this.{self::A::_#A#nonNullableInstanceField} = #t2;
get nullableInstanceField() → core::int? {
if(!this.{self::A::_#A#nullableInstanceField#isSet}) {
- this.{self::A::_#A#nullableInstanceField#isSet} = true;
this.{self::A::_#A#nullableInstanceField} = self::method();
+ this.{self::A::_#A#nullableInstanceField#isSet} = true;
}
return this.{self::A::_#A#nullableInstanceField};
}
@@ -35,8 +35,8 @@
self::A::_#nonNullableStaticField = #t5;
static get nullableStaticField() → core::int? {
if(!self::A::_#nullableStaticField#isSet) {
- self::A::_#nullableStaticField#isSet = true;
self::A::_#nullableStaticField = self::method();
+ self::A::_#nullableStaticField#isSet = true;
}
return self::A::_#nullableStaticField;
}
@@ -68,8 +68,8 @@
self::_#nonNullableTopLevelField = #t8;
static get nullableTopLevelField() → core::int? {
if(!self::_#nullableTopLevelField#isSet) {
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = self::method();
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.transformed.expect
index 9a2d29b..d9bfacd 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.weak.transformed.expect
@@ -20,8 +20,8 @@
this.{self::A::_#A#nonNullableInstanceField} = #t2;
get nullableInstanceField() → core::int? {
if(!this.{self::A::_#A#nullableInstanceField#isSet}) {
- this.{self::A::_#A#nullableInstanceField#isSet} = true;
this.{self::A::_#A#nullableInstanceField} = self::method();
+ this.{self::A::_#A#nullableInstanceField#isSet} = true;
}
return this.{self::A::_#A#nullableInstanceField};
}
@@ -35,8 +35,8 @@
self::A::_#nonNullableStaticField = #t5;
static get nullableStaticField() → core::int? {
if(!self::A::_#nullableStaticField#isSet) {
- self::A::_#nullableStaticField#isSet = true;
self::A::_#nullableStaticField = self::method();
+ self::A::_#nullableStaticField#isSet = true;
}
return self::A::_#nullableStaticField;
}
@@ -68,8 +68,8 @@
self::_#nonNullableTopLevelField = #t8;
static get nullableTopLevelField() → core::int? {
if(!self::_#nullableTopLevelField#isSet) {
- self::_#nullableTopLevelField#isSet = true;
self::_#nullableTopLevelField = self::method();
+ self::_#nullableTopLevelField#isSet = true;
}
return self::_#nullableTopLevelField;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
index 9e5e4e1..18cb216 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect
@@ -33,8 +33,8 @@
this.{self::Class::_#Class#lateInstanceField} = #t6;
get lateGenericField1() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField1#isSet}) {
- this.{self::Class::_#Class#lateGenericField1#isSet} = true;
this.{self::Class::_#Class#lateGenericField1} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField1#isSet} = true;
}
return let final self::Class::T? #t7 = this.{self::Class::_#Class#lateGenericField1} in #t7{self::Class::T%};
}
@@ -44,8 +44,8 @@
}
get lateGenericField2() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField2#isSet}) {
- this.{self::Class::_#Class#lateGenericField2#isSet} = true;
this.{self::Class::_#Class#lateGenericField2} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField2#isSet} = true;
}
return let final self::Class::T? #t9 = this.{self::Class::_#Class#lateGenericField2} in #t9{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
index 9e5e4e1..18cb216 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect
@@ -33,8 +33,8 @@
this.{self::Class::_#Class#lateInstanceField} = #t6;
get lateGenericField1() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField1#isSet}) {
- this.{self::Class::_#Class#lateGenericField1#isSet} = true;
this.{self::Class::_#Class#lateGenericField1} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField1#isSet} = true;
}
return let final self::Class::T? #t7 = this.{self::Class::_#Class#lateGenericField1} in #t7{self::Class::T%};
}
@@ -44,8 +44,8 @@
}
get lateGenericField2() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField2#isSet}) {
- this.{self::Class::_#Class#lateGenericField2#isSet} = true;
this.{self::Class::_#Class#lateGenericField2} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField2#isSet} = true;
}
return let final self::Class::T? #t9 = this.{self::Class::_#Class#lateGenericField2} in #t9{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
index 9e5e4e1..18cb216 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.expect
@@ -33,8 +33,8 @@
this.{self::Class::_#Class#lateInstanceField} = #t6;
get lateGenericField1() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField1#isSet}) {
- this.{self::Class::_#Class#lateGenericField1#isSet} = true;
this.{self::Class::_#Class#lateGenericField1} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField1#isSet} = true;
}
return let final self::Class::T? #t7 = this.{self::Class::_#Class#lateGenericField1} in #t7{self::Class::T%};
}
@@ -44,8 +44,8 @@
}
get lateGenericField2() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField2#isSet}) {
- this.{self::Class::_#Class#lateGenericField2#isSet} = true;
this.{self::Class::_#Class#lateGenericField2} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField2#isSet} = true;
}
return let final self::Class::T? #t9 = this.{self::Class::_#Class#lateGenericField2} in #t9{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
index 9e5e4e1..18cb216 100644
--- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.weak.transformed.expect
@@ -33,8 +33,8 @@
this.{self::Class::_#Class#lateInstanceField} = #t6;
get lateGenericField1() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField1#isSet}) {
- this.{self::Class::_#Class#lateGenericField1#isSet} = true;
this.{self::Class::_#Class#lateGenericField1} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField1#isSet} = true;
}
return let final self::Class::T? #t7 = this.{self::Class::_#Class#lateGenericField1} in #t7{self::Class::T%};
}
@@ -44,8 +44,8 @@
}
get lateGenericField2() → self::Class::T% {
if(!this.{self::Class::_#Class#lateGenericField2#isSet}) {
- this.{self::Class::_#Class#lateGenericField2#isSet} = true;
this.{self::Class::_#Class#lateGenericField2} = this.{self::Class::field};
+ this.{self::Class::_#Class#lateGenericField2#isSet} = true;
}
return let final self::Class::T? #t9 = this.{self::Class::_#Class#lateGenericField2} in #t9{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect
index ea54cfd..850426a 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect
@@ -45,8 +45,8 @@
final self::Class::T% #t7 = this.{self::Class::initLateGenericField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericField#isSet} = true;
this.{self::Class::_#Class#lateGenericField} = #t7;
+ this.{self::Class::_#Class#lateGenericField#isSet} = true;
}
return let final self::Class::T? #t8 = this.{self::Class::_#Class#lateGenericField} in #t8{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect
index ea54cfd..850426a 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect
@@ -45,8 +45,8 @@
final self::Class::T% #t7 = this.{self::Class::initLateGenericField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericField#isSet} = true;
this.{self::Class::_#Class#lateGenericField} = #t7;
+ this.{self::Class::_#Class#lateGenericField#isSet} = true;
}
return let final self::Class::T? #t8 = this.{self::Class::_#Class#lateGenericField} in #t8{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.expect
index ea54cfd..850426a 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.expect
@@ -45,8 +45,8 @@
final self::Class::T% #t7 = this.{self::Class::initLateGenericField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericField#isSet} = true;
this.{self::Class::_#Class#lateGenericField} = #t7;
+ this.{self::Class::_#Class#lateGenericField#isSet} = true;
}
return let final self::Class::T? #t8 = this.{self::Class::_#Class#lateGenericField} in #t8{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.transformed.expect
index ea54cfd..850426a 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.weak.transformed.expect
@@ -45,8 +45,8 @@
final self::Class::T% #t7 = this.{self::Class::initLateGenericField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericField#isSet} = true;
this.{self::Class::_#Class#lateGenericField} = #t7;
+ this.{self::Class::_#Class#lateGenericField#isSet} = true;
}
return let final self::Class::T? #t8 = this.{self::Class::_#Class#lateGenericField} in #t8{self::Class::T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
index 883b25a..2f84c91 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
@@ -22,8 +22,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
index 883b25a..2f84c91 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
@@ -22,8 +22,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
index 883b25a..2f84c91 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
@@ -22,8 +22,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
index 883b25a..2f84c91 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
@@ -22,8 +22,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect
index aa8b4d1..52eadc4 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect
@@ -28,8 +28,8 @@
final core::int? #t1 = self::Class::initLateStaticField1(87);
if(self::Class::_#lateStaticField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField1' has been assigned during initialization.");
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = #t1;
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -41,8 +41,8 @@
final core::int? #t2 = self::Class::initLateStaticField2(42);
if(self::Class::_#lateStaticField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField2' has been assigned during initialization.");
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = #t2;
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -59,8 +59,8 @@
final core::int? #t3 = this.{self::Class::initLateInstanceField}(16);
if(this.{self::Class::_#Class#lateInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = #t3;
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -72,8 +72,8 @@
final self::Class::T? #t4 = this.{self::Class::initLateGenericInstanceField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = #t4;
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -116,8 +116,8 @@
final core::int? #t5 = self::initLateTopLevelField1(123);
if(self::_#lateTopLevelField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateTopLevelField1' has been assigned during initialization.");
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = #t5;
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -129,8 +129,8 @@
final core::int? #t6 = self::Extension|initLateExtensionField1(87);
if(self::_#Extension|lateExtensionField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField1' has been assigned during initialization.");
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = #t6;
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -142,8 +142,8 @@
final core::int? #t7 = self::Extension|initLateExtensionField2(42);
if(self::_#Extension|lateExtensionField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField2' has been assigned during initialization.");
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = #t7;
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect
index aa8b4d1..52eadc4 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect
@@ -28,8 +28,8 @@
final core::int? #t1 = self::Class::initLateStaticField1(87);
if(self::Class::_#lateStaticField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField1' has been assigned during initialization.");
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = #t1;
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -41,8 +41,8 @@
final core::int? #t2 = self::Class::initLateStaticField2(42);
if(self::Class::_#lateStaticField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField2' has been assigned during initialization.");
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = #t2;
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -59,8 +59,8 @@
final core::int? #t3 = this.{self::Class::initLateInstanceField}(16);
if(this.{self::Class::_#Class#lateInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = #t3;
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -72,8 +72,8 @@
final self::Class::T? #t4 = this.{self::Class::initLateGenericInstanceField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = #t4;
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -116,8 +116,8 @@
final core::int? #t5 = self::initLateTopLevelField1(123);
if(self::_#lateTopLevelField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateTopLevelField1' has been assigned during initialization.");
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = #t5;
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -129,8 +129,8 @@
final core::int? #t6 = self::Extension|initLateExtensionField1(87);
if(self::_#Extension|lateExtensionField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField1' has been assigned during initialization.");
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = #t6;
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -142,8 +142,8 @@
final core::int? #t7 = self::Extension|initLateExtensionField2(42);
if(self::_#Extension|lateExtensionField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField2' has been assigned during initialization.");
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = #t7;
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.expect
index aa8b4d1..52eadc4 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.expect
@@ -28,8 +28,8 @@
final core::int? #t1 = self::Class::initLateStaticField1(87);
if(self::Class::_#lateStaticField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField1' has been assigned during initialization.");
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = #t1;
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -41,8 +41,8 @@
final core::int? #t2 = self::Class::initLateStaticField2(42);
if(self::Class::_#lateStaticField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField2' has been assigned during initialization.");
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = #t2;
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -59,8 +59,8 @@
final core::int? #t3 = this.{self::Class::initLateInstanceField}(16);
if(this.{self::Class::_#Class#lateInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = #t3;
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -72,8 +72,8 @@
final self::Class::T? #t4 = this.{self::Class::initLateGenericInstanceField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = #t4;
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -116,8 +116,8 @@
final core::int? #t5 = self::initLateTopLevelField1(123);
if(self::_#lateTopLevelField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateTopLevelField1' has been assigned during initialization.");
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = #t5;
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -129,8 +129,8 @@
final core::int? #t6 = self::Extension|initLateExtensionField1(87);
if(self::_#Extension|lateExtensionField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField1' has been assigned during initialization.");
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = #t6;
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -142,8 +142,8 @@
final core::int? #t7 = self::Extension|initLateExtensionField2(42);
if(self::_#Extension|lateExtensionField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField2' has been assigned during initialization.");
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = #t7;
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.transformed.expect
index aa8b4d1..52eadc4 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.weak.transformed.expect
@@ -28,8 +28,8 @@
final core::int? #t1 = self::Class::initLateStaticField1(87);
if(self::Class::_#lateStaticField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField1' has been assigned during initialization.");
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = #t1;
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -41,8 +41,8 @@
final core::int? #t2 = self::Class::initLateStaticField2(42);
if(self::Class::_#lateStaticField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateStaticField2' has been assigned during initialization.");
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = #t2;
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -59,8 +59,8 @@
final core::int? #t3 = this.{self::Class::initLateInstanceField}(16);
if(this.{self::Class::_#Class#lateInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = #t3;
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -72,8 +72,8 @@
final self::Class::T? #t4 = this.{self::Class::initLateGenericInstanceField}(this.{self::Class::field});
if(this.{self::Class::_#Class#lateGenericInstanceField#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'lateGenericInstanceField' has been assigned during initialization.");
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = #t4;
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -116,8 +116,8 @@
final core::int? #t5 = self::initLateTopLevelField1(123);
if(self::_#lateTopLevelField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateTopLevelField1' has been assigned during initialization.");
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = #t5;
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -129,8 +129,8 @@
final core::int? #t6 = self::Extension|initLateExtensionField1(87);
if(self::_#Extension|lateExtensionField1#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField1' has been assigned during initialization.");
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = #t6;
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -142,8 +142,8 @@
final core::int? #t7 = self::Extension|initLateExtensionField2(42);
if(self::_#Extension|lateExtensionField2#isSet)
throw new _in::LateInitializationErrorImpl::•("Field 'lateExtensionField2' has been assigned during initialization.");
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = #t7;
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
index dc6b6ad..a134538 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
@@ -11,8 +11,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = initLateLocal.call(123);
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -28,8 +28,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
index dc6b6ad..a134538 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
@@ -11,8 +11,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = initLateLocal.call(123);
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -28,8 +28,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
index dc6b6ad..a134538 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
@@ -11,8 +11,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = initLateLocal.call(123);
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -28,8 +28,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
index dc6b6ad..a134538 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
@@ -11,8 +11,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = initLateLocal.call(123);
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -28,8 +28,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = initLateGenericLocal.call(value);
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
index 3ad795c..e3a3c24 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.expect
@@ -119,8 +119,8 @@
return null;
static get field1() → asy::FutureOr<dynamic> {
if(!self::_#field1#isSet) {
- self::_#field1#isSet = true;
self::_#field1 = self::method1();
+ self::_#field1#isSet = true;
}
return self::_#field1;
}
@@ -130,8 +130,8 @@
}
static get field2() → asy::FutureOr<dynamic>? {
if(!self::_#field2#isSet) {
- self::_#field2#isSet = true;
self::_#field2 = self::method2();
+ self::_#field2#isSet = true;
}
return self::_#field2;
}
@@ -141,8 +141,8 @@
}
static get field3() → asy::FutureOr<dynamic> {
if(!self::_#field3#isSet) {
- self::_#field3#isSet = true;
self::_#field3 = self::method3();
+ self::_#field3#isSet = true;
}
return self::_#field3;
}
@@ -156,8 +156,8 @@
self::_#field4 = #t16;
static get field5() → asy::FutureOr<core::int?> {
if(!self::_#field5#isSet) {
- self::_#field5#isSet = true;
self::_#field5 = self::method5();
+ self::_#field5#isSet = true;
}
return self::_#field5;
}
@@ -167,8 +167,8 @@
}
static get field6() → asy::FutureOr<core::int?>? {
if(!self::_#field6#isSet) {
- self::_#field6#isSet = true;
self::_#field6 = self::method6();
+ self::_#field6#isSet = true;
}
return self::_#field6;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
index 3ad795c..e3a3c24 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.strong.transformed.expect
@@ -119,8 +119,8 @@
return null;
static get field1() → asy::FutureOr<dynamic> {
if(!self::_#field1#isSet) {
- self::_#field1#isSet = true;
self::_#field1 = self::method1();
+ self::_#field1#isSet = true;
}
return self::_#field1;
}
@@ -130,8 +130,8 @@
}
static get field2() → asy::FutureOr<dynamic>? {
if(!self::_#field2#isSet) {
- self::_#field2#isSet = true;
self::_#field2 = self::method2();
+ self::_#field2#isSet = true;
}
return self::_#field2;
}
@@ -141,8 +141,8 @@
}
static get field3() → asy::FutureOr<dynamic> {
if(!self::_#field3#isSet) {
- self::_#field3#isSet = true;
self::_#field3 = self::method3();
+ self::_#field3#isSet = true;
}
return self::_#field3;
}
@@ -156,8 +156,8 @@
self::_#field4 = #t16;
static get field5() → asy::FutureOr<core::int?> {
if(!self::_#field5#isSet) {
- self::_#field5#isSet = true;
self::_#field5 = self::method5();
+ self::_#field5#isSet = true;
}
return self::_#field5;
}
@@ -167,8 +167,8 @@
}
static get field6() → asy::FutureOr<core::int?>? {
if(!self::_#field6#isSet) {
- self::_#field6#isSet = true;
self::_#field6 = self::method6();
+ self::_#field6#isSet = true;
}
return self::_#field6;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
index 3ad795c..e3a3c24 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.expect
@@ -119,8 +119,8 @@
return null;
static get field1() → asy::FutureOr<dynamic> {
if(!self::_#field1#isSet) {
- self::_#field1#isSet = true;
self::_#field1 = self::method1();
+ self::_#field1#isSet = true;
}
return self::_#field1;
}
@@ -130,8 +130,8 @@
}
static get field2() → asy::FutureOr<dynamic>? {
if(!self::_#field2#isSet) {
- self::_#field2#isSet = true;
self::_#field2 = self::method2();
+ self::_#field2#isSet = true;
}
return self::_#field2;
}
@@ -141,8 +141,8 @@
}
static get field3() → asy::FutureOr<dynamic> {
if(!self::_#field3#isSet) {
- self::_#field3#isSet = true;
self::_#field3 = self::method3();
+ self::_#field3#isSet = true;
}
return self::_#field3;
}
@@ -156,8 +156,8 @@
self::_#field4 = #t16;
static get field5() → asy::FutureOr<core::int?> {
if(!self::_#field5#isSet) {
- self::_#field5#isSet = true;
self::_#field5 = self::method5();
+ self::_#field5#isSet = true;
}
return self::_#field5;
}
@@ -167,8 +167,8 @@
}
static get field6() → asy::FutureOr<core::int?>? {
if(!self::_#field6#isSet) {
- self::_#field6#isSet = true;
self::_#field6 = self::method6();
+ self::_#field6#isSet = true;
}
return self::_#field6;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
index 3ad795c..e3a3c24 100644
--- a/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.weak.transformed.expect
@@ -119,8 +119,8 @@
return null;
static get field1() → asy::FutureOr<dynamic> {
if(!self::_#field1#isSet) {
- self::_#field1#isSet = true;
self::_#field1 = self::method1();
+ self::_#field1#isSet = true;
}
return self::_#field1;
}
@@ -130,8 +130,8 @@
}
static get field2() → asy::FutureOr<dynamic>? {
if(!self::_#field2#isSet) {
- self::_#field2#isSet = true;
self::_#field2 = self::method2();
+ self::_#field2#isSet = true;
}
return self::_#field2;
}
@@ -141,8 +141,8 @@
}
static get field3() → asy::FutureOr<dynamic> {
if(!self::_#field3#isSet) {
- self::_#field3#isSet = true;
self::_#field3 = self::method3();
+ self::_#field3#isSet = true;
}
return self::_#field3;
}
@@ -156,8 +156,8 @@
self::_#field4 = #t16;
static get field5() → asy::FutureOr<core::int?> {
if(!self::_#field5#isSet) {
- self::_#field5#isSet = true;
self::_#field5 = self::method5();
+ self::_#field5#isSet = true;
}
return self::_#field5;
}
@@ -167,8 +167,8 @@
}
static get field6() → asy::FutureOr<core::int?>? {
if(!self::_#field6#isSet) {
- self::_#field6#isSet = true;
self::_#field6 = self::method6();
+ self::_#field6#isSet = true;
}
return self::_#field6;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
index 25a5097..9fbaf26 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.expect
@@ -16,8 +16,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
index 25a5097..9fbaf26 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.strong.transformed.expect
@@ -16,8 +16,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
index 25a5097..9fbaf26 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.expect
@@ -16,8 +16,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
index 25a5097..9fbaf26 100644
--- a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.weak.transformed.expect
@@ -16,8 +16,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
index 6a2319d..e44eb03 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect
@@ -19,8 +19,8 @@
return 87;
static get lateStaticField1() → core::int? {
if(!self::Class::_#lateStaticField1#isSet) {
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = self::Class::lateStaticField1Init();
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -32,8 +32,8 @@
return 42;
static get lateStaticField2() → core::int? {
if(!self::Class::_#lateStaticField2#isSet) {
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = self::Class::lateStaticField2Init();
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -50,8 +50,8 @@
return 16;
get lateInstanceField() → core::int? {
if(!this.{self::Class::_#Class#lateInstanceField#isSet}) {
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = this.{self::Class::lateInstanceFieldInit}();
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -63,8 +63,8 @@
return this.{self::Class::field};
get lateGenericInstanceField() → self::Class::T? {
if(!this.{self::Class::_#Class#lateGenericInstanceField#isSet}) {
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = this.{self::Class::lateGenericInstanceFieldInit}();
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -104,8 +104,8 @@
return 123;
static get lateTopLevelField1() → core::int? {
if(!self::_#lateTopLevelField1#isSet) {
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = self::lateTopLevelField1Init();
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -117,8 +117,8 @@
return 87;
static get Extension|lateExtensionField1() → core::int? {
if(!self::_#Extension|lateExtensionField1#isSet) {
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = self::Extension|lateExtensionField1Init();
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -130,8 +130,8 @@
return 42;
static get Extension|lateExtensionField2() → core::int? {
if(!self::_#Extension|lateExtensionField2#isSet) {
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = self::Extension|lateExtensionField2Init();
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
index 6a2319d..e44eb03 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect
@@ -19,8 +19,8 @@
return 87;
static get lateStaticField1() → core::int? {
if(!self::Class::_#lateStaticField1#isSet) {
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = self::Class::lateStaticField1Init();
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -32,8 +32,8 @@
return 42;
static get lateStaticField2() → core::int? {
if(!self::Class::_#lateStaticField2#isSet) {
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = self::Class::lateStaticField2Init();
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -50,8 +50,8 @@
return 16;
get lateInstanceField() → core::int? {
if(!this.{self::Class::_#Class#lateInstanceField#isSet}) {
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = this.{self::Class::lateInstanceFieldInit}();
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -63,8 +63,8 @@
return this.{self::Class::field};
get lateGenericInstanceField() → self::Class::T? {
if(!this.{self::Class::_#Class#lateGenericInstanceField#isSet}) {
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = this.{self::Class::lateGenericInstanceFieldInit}();
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -104,8 +104,8 @@
return 123;
static get lateTopLevelField1() → core::int? {
if(!self::_#lateTopLevelField1#isSet) {
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = self::lateTopLevelField1Init();
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -117,8 +117,8 @@
return 87;
static get Extension|lateExtensionField1() → core::int? {
if(!self::_#Extension|lateExtensionField1#isSet) {
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = self::Extension|lateExtensionField1Init();
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -130,8 +130,8 @@
return 42;
static get Extension|lateExtensionField2() → core::int? {
if(!self::_#Extension|lateExtensionField2#isSet) {
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = self::Extension|lateExtensionField2Init();
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
index 6a2319d..e44eb03 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.expect
@@ -19,8 +19,8 @@
return 87;
static get lateStaticField1() → core::int? {
if(!self::Class::_#lateStaticField1#isSet) {
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = self::Class::lateStaticField1Init();
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -32,8 +32,8 @@
return 42;
static get lateStaticField2() → core::int? {
if(!self::Class::_#lateStaticField2#isSet) {
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = self::Class::lateStaticField2Init();
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -50,8 +50,8 @@
return 16;
get lateInstanceField() → core::int? {
if(!this.{self::Class::_#Class#lateInstanceField#isSet}) {
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = this.{self::Class::lateInstanceFieldInit}();
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -63,8 +63,8 @@
return this.{self::Class::field};
get lateGenericInstanceField() → self::Class::T? {
if(!this.{self::Class::_#Class#lateGenericInstanceField#isSet}) {
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = this.{self::Class::lateGenericInstanceFieldInit}();
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -104,8 +104,8 @@
return 123;
static get lateTopLevelField1() → core::int? {
if(!self::_#lateTopLevelField1#isSet) {
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = self::lateTopLevelField1Init();
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -117,8 +117,8 @@
return 87;
static get Extension|lateExtensionField1() → core::int? {
if(!self::_#Extension|lateExtensionField1#isSet) {
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = self::Extension|lateExtensionField1Init();
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -130,8 +130,8 @@
return 42;
static get Extension|lateExtensionField2() → core::int? {
if(!self::_#Extension|lateExtensionField2#isSet) {
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = self::Extension|lateExtensionField2Init();
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
index 6a2319d..e44eb03 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.weak.transformed.expect
@@ -19,8 +19,8 @@
return 87;
static get lateStaticField1() → core::int? {
if(!self::Class::_#lateStaticField1#isSet) {
- self::Class::_#lateStaticField1#isSet = true;
self::Class::_#lateStaticField1 = self::Class::lateStaticField1Init();
+ self::Class::_#lateStaticField1#isSet = true;
}
return self::Class::_#lateStaticField1;
}
@@ -32,8 +32,8 @@
return 42;
static get lateStaticField2() → core::int? {
if(!self::Class::_#lateStaticField2#isSet) {
- self::Class::_#lateStaticField2#isSet = true;
self::Class::_#lateStaticField2 = self::Class::lateStaticField2Init();
+ self::Class::_#lateStaticField2#isSet = true;
}
return self::Class::_#lateStaticField2;
}
@@ -50,8 +50,8 @@
return 16;
get lateInstanceField() → core::int? {
if(!this.{self::Class::_#Class#lateInstanceField#isSet}) {
- this.{self::Class::_#Class#lateInstanceField#isSet} = true;
this.{self::Class::_#Class#lateInstanceField} = this.{self::Class::lateInstanceFieldInit}();
+ this.{self::Class::_#Class#lateInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateInstanceField};
}
@@ -63,8 +63,8 @@
return this.{self::Class::field};
get lateGenericInstanceField() → self::Class::T? {
if(!this.{self::Class::_#Class#lateGenericInstanceField#isSet}) {
- this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
this.{self::Class::_#Class#lateGenericInstanceField} = this.{self::Class::lateGenericInstanceFieldInit}();
+ this.{self::Class::_#Class#lateGenericInstanceField#isSet} = true;
}
return this.{self::Class::_#Class#lateGenericInstanceField};
}
@@ -104,8 +104,8 @@
return 123;
static get lateTopLevelField1() → core::int? {
if(!self::_#lateTopLevelField1#isSet) {
- self::_#lateTopLevelField1#isSet = true;
self::_#lateTopLevelField1 = self::lateTopLevelField1Init();
+ self::_#lateTopLevelField1#isSet = true;
}
return self::_#lateTopLevelField1;
}
@@ -117,8 +117,8 @@
return 87;
static get Extension|lateExtensionField1() → core::int? {
if(!self::_#Extension|lateExtensionField1#isSet) {
- self::_#Extension|lateExtensionField1#isSet = true;
self::_#Extension|lateExtensionField1 = self::Extension|lateExtensionField1Init();
+ self::_#Extension|lateExtensionField1#isSet = true;
}
return self::_#Extension|lateExtensionField1;
}
@@ -130,8 +130,8 @@
return 42;
static get Extension|lateExtensionField2() → core::int? {
if(!self::_#Extension|lateExtensionField2#isSet) {
- self::_#Extension|lateExtensionField2#isSet = true;
self::_#Extension|lateExtensionField2 = self::Extension|lateExtensionField2Init();
+ self::_#Extension|lateExtensionField2#isSet = true;
}
return self::_#Extension|lateExtensionField2;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
index 25dee5a..dea8137 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.expect
@@ -9,8 +9,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = self::lateLocalInit();
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -26,8 +26,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
index 25dee5a..dea8137 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.strong.transformed.expect
@@ -9,8 +9,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = self::lateLocalInit();
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -26,8 +26,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
index 25dee5a..dea8137 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.expect
@@ -9,8 +9,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = self::lateLocalInit();
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -26,8 +26,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
index 25dee5a..dea8137 100644
--- a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.weak.transformed.expect
@@ -9,8 +9,8 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- #lateLocal#isSet = true;
lateLocal = self::lateLocalInit();
+ #lateLocal#isSet = true;
}
return lateLocal;
}
@@ -26,8 +26,8 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- #lateGenericLocal#isSet = true;
lateGenericLocal = value1;
+ #lateGenericLocal#isSet = true;
}
return lateGenericLocal;
}
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.expect
index f5a665d..6e5f0ef 100644
--- a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.expect
@@ -50,8 +50,8 @@
final core::int? #t6 = 2;
if(this.{self::C::_#C#y#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'y' has been assigned during initialization.");
- this.{self::C::_#C#y#isSet} = true;
this.{self::C::_#C#y} = #t6;
+ this.{self::C::_#C#y#isSet} = true;
}
return this.{self::C::_#C#y};
}
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.transformed.expect
index f5a665d..6e5f0ef 100644
--- a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.strong.transformed.expect
@@ -50,8 +50,8 @@
final core::int? #t6 = 2;
if(this.{self::C::_#C#y#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'y' has been assigned during initialization.");
- this.{self::C::_#C#y#isSet} = true;
this.{self::C::_#C#y} = #t6;
+ this.{self::C::_#C#y#isSet} = true;
}
return this.{self::C::_#C#y};
}
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.expect
index f5a665d..6e5f0ef 100644
--- a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.expect
@@ -50,8 +50,8 @@
final core::int? #t6 = 2;
if(this.{self::C::_#C#y#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'y' has been assigned during initialization.");
- this.{self::C::_#C#y#isSet} = true;
this.{self::C::_#C#y} = #t6;
+ this.{self::C::_#C#y#isSet} = true;
}
return this.{self::C::_#C#y};
}
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.transformed.expect
index f5a665d..6e5f0ef 100644
--- a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.weak.transformed.expect
@@ -50,8 +50,8 @@
final core::int? #t6 = 2;
if(this.{self::C::_#C#y#isSet})
throw new _in::LateInitializationErrorImpl::•("Field 'y' has been assigned during initialization.");
- this.{self::C::_#C#y#isSet} = true;
this.{self::C::_#C#y} = #t6;
+ this.{self::C::_#C#y#isSet} = true;
}
return this.{self::C::_#C#y};
}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
index 7b6d380..1cc4a59 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.expect
@@ -12,8 +12,8 @@
core::bool #result#isSet = false;
function #result#get() → self::Class::E% {
if(!#result#isSet) {
- #result#isSet = true;
result = this.{self::Class::field};
+ #result#isSet = true;
}
return result{self::Class::E%};
}
@@ -37,8 +37,8 @@
core::bool #result#isSet = false;
function #result#get() → core::int? {
if(!#result#isSet) {
- #result#isSet = true;
result = value;
+ #result#isSet = true;
}
return result;
}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
index 7b6d380..1cc4a59 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.strong.transformed.expect
@@ -12,8 +12,8 @@
core::bool #result#isSet = false;
function #result#get() → self::Class::E% {
if(!#result#isSet) {
- #result#isSet = true;
result = this.{self::Class::field};
+ #result#isSet = true;
}
return result{self::Class::E%};
}
@@ -37,8 +37,8 @@
core::bool #result#isSet = false;
function #result#get() → core::int? {
if(!#result#isSet) {
- #result#isSet = true;
result = value;
+ #result#isSet = true;
}
return result;
}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
index 7b6d380..1cc4a59 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.expect
@@ -12,8 +12,8 @@
core::bool #result#isSet = false;
function #result#get() → self::Class::E% {
if(!#result#isSet) {
- #result#isSet = true;
result = this.{self::Class::field};
+ #result#isSet = true;
}
return result{self::Class::E%};
}
@@ -37,8 +37,8 @@
core::bool #result#isSet = false;
function #result#get() → core::int? {
if(!#result#isSet) {
- #result#isSet = true;
result = value;
+ #result#isSet = true;
}
return result;
}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
index 7b6d380..1cc4a59 100644
--- a/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.weak.transformed.expect
@@ -12,8 +12,8 @@
core::bool #result#isSet = false;
function #result#get() → self::Class::E% {
if(!#result#isSet) {
- #result#isSet = true;
result = this.{self::Class::field};
+ #result#isSet = true;
}
return result{self::Class::E%};
}
@@ -37,8 +37,8 @@
core::bool #result#isSet = false;
function #result#get() → core::int? {
if(!#result#isSet) {
- #result#isSet = true;
result = value;
+ #result#isSet = true;
}
return result;
}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect
index ac11cde..95a3402 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect
@@ -17,7 +17,10 @@
method g() → void {}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}() in let final void #t3 = #t1.{self::C::h}() in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}();
+ #t1.{self::C::h}();
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect
index ac11cde..95a3402 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect
@@ -17,7 +17,10 @@
method g() → void {}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}() in let final void #t3 = #t1.{self::C::h}() in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}();
+ #t1.{self::C::h}();
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.expect
index ac11cde..95a3402 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.expect
@@ -17,7 +17,10 @@
method g() → void {}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}() in let final void #t3 = #t1.{self::C::h}() in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}();
+ #t1.{self::C::h}();
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.transformed.expect
index ac11cde..95a3402 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.weak.transformed.expect
@@ -17,7 +17,10 @@
method g() → void {}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}() in let final void #t3 = #t1.{self::C::h}() in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}();
+ #t1.{self::C::h}();
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect
index e8d7ee9..b21ab32 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect
@@ -35,7 +35,10 @@
}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")! in let final void #t3 = #t1.{self::C::h}()!.{self::C::y} = 2 in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")!;
+ #t1.{self::C::h}()!.{self::C::y} = 2;
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect
index e8d7ee9..b21ab32 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect
@@ -35,7 +35,10 @@
}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")! in let final void #t3 = #t1.{self::C::h}()!.{self::C::y} = 2 in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")!;
+ #t1.{self::C::h}()!.{self::C::y} = 2;
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.expect
index e8d7ee9..b21ab32 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.expect
@@ -35,7 +35,10 @@
}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")! in let final void #t3 = #t1.{self::C::h}()!.{self::C::y} = 2 in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")!;
+ #t1.{self::C::h}()!.{self::C::y} = 2;
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.transformed.expect
index e8d7ee9..b21ab32 100644
--- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.weak.transformed.expect
@@ -35,7 +35,10 @@
}
}
static method test(self::C x) → void {
- let final self::C #t1 = x in let final void #t2 = #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")! in let final void #t3 = #t1.{self::C::h}()!.{self::C::y} = 2 in #t1;
+ let final self::C #t1 = x in block {
+ #t1.{self::C::f}()!.{self::D::g}().{self::D::[]}("Hi!")!;
+ #t1.{self::C::h}()!.{self::C::y} = 2;
+ } =>#t1;
}
static method main() → dynamic {
self::test(new self::C::•());
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
index 1e6793a..b67570c 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect
@@ -19,8 +19,18 @@
return () → self::Class => self::Extension|extensionMethod(#this);
static method main() → dynamic {
self::Class? c;
- let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final void #t2 = #t1{self::Class}.{self::Class::method}() in #t1;
- let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : let final void #t4 = #t3{self::Class}.{self::Class::method}() in let final void #t5 = #t3{self::Class}.{self::Class::method}() in #t3;
- let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{self::Class?} null : let final void #t7 = self::Extension|extensionMethod(#t6{self::Class}) in #t6;
- let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{self::Class?} null : let final void #t9 = self::Extension|extensionMethod(#t8{self::Class}) in let final void #t10 = self::Extension|extensionMethod(#t8{self::Class}) in #t8;
+ let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t1{self::Class}.{self::Class::method}();
+ } =>#t1;
+ let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t2{self::Class}.{self::Class::method}();
+ #t2{self::Class}.{self::Class::method}();
+ } =>#t2;
+ let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t3{self::Class});
+ } =>#t3;
+ let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t4{self::Class});
+ self::Extension|extensionMethod(#t4{self::Class});
+ } =>#t4;
}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
index 1e6793a..b67570c 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect
@@ -19,8 +19,18 @@
return () → self::Class => self::Extension|extensionMethod(#this);
static method main() → dynamic {
self::Class? c;
- let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final void #t2 = #t1{self::Class}.{self::Class::method}() in #t1;
- let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : let final void #t4 = #t3{self::Class}.{self::Class::method}() in let final void #t5 = #t3{self::Class}.{self::Class::method}() in #t3;
- let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{self::Class?} null : let final void #t7 = self::Extension|extensionMethod(#t6{self::Class}) in #t6;
- let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{self::Class?} null : let final void #t9 = self::Extension|extensionMethod(#t8{self::Class}) in let final void #t10 = self::Extension|extensionMethod(#t8{self::Class}) in #t8;
+ let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t1{self::Class}.{self::Class::method}();
+ } =>#t1;
+ let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t2{self::Class}.{self::Class::method}();
+ #t2{self::Class}.{self::Class::method}();
+ } =>#t2;
+ let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t3{self::Class});
+ } =>#t3;
+ let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t4{self::Class});
+ self::Extension|extensionMethod(#t4{self::Class});
+ } =>#t4;
}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
index 1e6793a..b67570c 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.expect
@@ -19,8 +19,18 @@
return () → self::Class => self::Extension|extensionMethod(#this);
static method main() → dynamic {
self::Class? c;
- let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final void #t2 = #t1{self::Class}.{self::Class::method}() in #t1;
- let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : let final void #t4 = #t3{self::Class}.{self::Class::method}() in let final void #t5 = #t3{self::Class}.{self::Class::method}() in #t3;
- let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{self::Class?} null : let final void #t7 = self::Extension|extensionMethod(#t6{self::Class}) in #t6;
- let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{self::Class?} null : let final void #t9 = self::Extension|extensionMethod(#t8{self::Class}) in let final void #t10 = self::Extension|extensionMethod(#t8{self::Class}) in #t8;
+ let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t1{self::Class}.{self::Class::method}();
+ } =>#t1;
+ let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t2{self::Class}.{self::Class::method}();
+ #t2{self::Class}.{self::Class::method}();
+ } =>#t2;
+ let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t3{self::Class});
+ } =>#t3;
+ let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t4{self::Class});
+ self::Extension|extensionMethod(#t4{self::Class});
+ } =>#t4;
}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
index 1e6793a..b67570c 100644
--- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.weak.transformed.expect
@@ -19,8 +19,18 @@
return () → self::Class => self::Extension|extensionMethod(#this);
static method main() → dynamic {
self::Class? c;
- let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : let final void #t2 = #t1{self::Class}.{self::Class::method}() in #t1;
- let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : let final void #t4 = #t3{self::Class}.{self::Class::method}() in let final void #t5 = #t3{self::Class}.{self::Class::method}() in #t3;
- let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{self::Class?} null : let final void #t7 = self::Extension|extensionMethod(#t6{self::Class}) in #t6;
- let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{self::Class?} null : let final void #t9 = self::Extension|extensionMethod(#t8{self::Class}) in let final void #t10 = self::Extension|extensionMethod(#t8{self::Class}) in #t8;
+ let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t1{self::Class}.{self::Class::method}();
+ } =>#t1;
+ let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{self::Class?} null : block {
+ #t2{self::Class}.{self::Class::method}();
+ #t2{self::Class}.{self::Class::method}();
+ } =>#t2;
+ let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t3{self::Class});
+ } =>#t3;
+ let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{self::Class?} null : block {
+ self::Extension|extensionMethod(#t4{self::Class});
+ self::Extension|extensionMethod(#t4{self::Class});
+ } =>#t4;
}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
index 5f0452d..ea9d20e 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.expect
@@ -132,56 +132,62 @@
return 42;
static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
- let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : let final void #t4 = #t3.{core::String::length} in #t3;
- let final core::String #t5 = s in #t5.{core::String::==}(null) ?{core::String} "foo" : #t5;
+ let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : block {
+ #t3.{core::String::length};
+ } =>#t3;
+ let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
s.{core::String::==}(null) ?{core::String} s = "foo" : null;
block {
- final core::List<core::String> #t6 = <core::String>[];
- final core::Iterable<core::String>? #t7 = l;
- if(!#t7.{core::Object::==}(null))
- for (final core::String #t8 in #t7{core::Iterable<core::String>})
- #t6.{core::List::add}(#t8);
- } =>#t6;
+ final core::List<core::String> #t5 = <core::String>[];
+ final core::Iterable<core::String>? #t6 = l;
+ if(!#t6.{core::Object::==}(null))
+ for (final core::String #t7 in #t6{core::Iterable<core::String>})
+ #t5.{core::List::add}(#t7);
+ } =>#t5;
core::Set<core::String> a = block {
- final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t10 = l;
- if(!#t10.{core::Object::==}(null))
- for (final dynamic #t11 in #t10{core::Iterable<core::String>}) {
- final core::String #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::String;
- #t9.{core::Set::add}(#t12);
+ final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t9 = l;
+ if(!#t9.{core::Object::==}(null))
+ for (final dynamic #t10 in #t9{core::Iterable<core::String>}) {
+ final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
+ #t8.{core::Set::add}(#t11);
}
- } =>#t9;
+ } =>#t8;
block {
- final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t14 = l;
- if(!#t14.{core::Object::==}(null))
- for (final core::String #t15 in #t14{core::Iterable<core::String>})
- #t13.{core::Set::add}(#t15);
- } =>#t13;
+ final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t13 = l;
+ if(!#t13.{core::Object::==}(null))
+ for (final core::String #t14 in #t13{core::Iterable<core::String>})
+ #t12.{core::Set::add}(#t14);
+ } =>#t12;
core::Map<core::String, core::int> b = block {
- final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t17 = m;
- if(!#t17.{core::Object::==}(null))
- for (final core::MapEntry<core::String, core::int> #t18 in #t17{core::Map<core::String, core::int>}.{core::Map::entries})
- #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
- } =>#t16;
+ final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t16 = m;
+ if(!#t16.{core::Object::==}(null))
+ for (final core::MapEntry<core::String, core::int> #t17 in #t16{core::Map<core::String, core::int>}.{core::Map::entries})
+ #t15.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+ } =>#t15;
block {
- final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t20 = m;
- if(!#t20.{core::Object::==}(null))
- for (final core::MapEntry<core::String, core::int> #t21 in #t20{core::Map<core::String, core::int>}.{core::Map::entries})
- #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
- } =>#t19;
+ final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t19 = m;
+ if(!#t19.{core::Object::==}(null))
+ for (final core::MapEntry<core::String, core::int> #t20 in #t19{core::Map<core::String, core::int>}.{core::Map::entries})
+ #t18.{core::Map::[]=}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
+ } =>#t18;
s!;
- let final core::String #t22 = s in #t22.{core::String::==}(null) ?{core::String?} null : #t22.{core::String::substring}(0, 0);
- let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = 42;
- let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length} = #t24.{core::List::length}.{core::num::+}(42);
- let final core::List<core::String> #t25 = l in #t25.{core::List::==}(null) ?{core::int?} null : #t25.{core::List::length}.{core::num::==}(null) ?{core::int} #t25.{core::List::length} = 42 : null;
- let final core::String #t26 = s in #t26.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t26);
- let final core::String #t27 = s in let final core::int #t28 = 42 in self::E|[](#t27, #t28).{core::num::==}(null) ?{core::int} self::E|[]=(#t27, #t28, 42) : null;
- let final core::List<core::String> #t29 = l in let final core::int #t30 = 42 in #t29.{core::List::[]}(#t30).{core::String::==}(null) ?{core::String} #t29.{core::List::[]=}(#t30, "foo") : null;
- let final core::List<core::String> #t31 = l in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
- let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t33 = #t32.{core::List::length} = 42 in #t32;
- let final core::List<core::String> #t34 = l in #t34.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t35 = let final core::List<core::String> #t36 = #t34 in #t36.{core::List::length}.{core::num::==}(null) ?{core::int} #t36.{core::List::length} = 42 : null in #t34;
+ let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
+ let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
+ let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
+ let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
+ let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
+ let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
+ let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
+ let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
+ let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ #t31.{core::List::length} = 42;
+ } =>#t31;
+ let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
+ } =>#t32;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
index 2e60ba3..301af59 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.strong.transformed.expect
@@ -132,77 +132,83 @@
return 42;
static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
- let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : let final void #t4 = #t3.{core::String::length} in #t3;
- let final core::String #t5 = s in #t5.{core::String::==}(null) ?{core::String} "foo" : #t5;
+ let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : block {
+ #t3.{core::String::length};
+ } =>#t3;
+ let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
s.{core::String::==}(null) ?{core::String} s = "foo" : null;
block {
- final core::List<core::String> #t6 = <core::String>[];
- final core::Iterable<core::String>? #t7 = l;
- if(!#t7.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t7{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::List<core::String> #t5 = <core::String>[];
+ final core::Iterable<core::String>? #t6 = l;
+ if(!#t6.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t6{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::String #t8 = :sync-for-iterator.{core::Iterator::current};
- #t6.{core::List::add}(#t8);
+ final core::String #t7 = :sync-for-iterator.{core::Iterator::current};
+ #t5.{core::List::add}(#t7);
}
}
- } =>#t6;
+ } =>#t5;
core::Set<core::String> a = block {
- final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t10 = l;
- if(!#t10.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t10{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t9 = l;
+ if(!#t9.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t9{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
{
- final core::String #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::String;
- #t9.{core::Set::add}(#t12);
+ final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
+ #t8.{core::Set::add}(#t11);
}
}
}
- } =>#t9;
+ } =>#t8;
block {
- final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t14 = l;
- if(!#t14.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t14{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t13 = l;
+ if(!#t13.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t13{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::String #t15 = :sync-for-iterator.{core::Iterator::current};
- #t13.{core::Set::add}(#t15);
+ final core::String #t14 = :sync-for-iterator.{core::Iterator::current};
+ #t12.{core::Set::add}(#t14);
}
}
- } =>#t13;
+ } =>#t12;
core::Map<core::String, core::int> b = block {
- final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t17 = m;
- if(!#t17.{core::Object::==}(null)) {
- core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+ final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t16 = m;
+ if(!#t16.{core::Object::==}(null)) {
+ core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t16{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
- #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
+ final core::MapEntry<core::String, core::int> #t17 = :sync-for-iterator.{core::Iterator::current};
+ #t15.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
}
}
- } =>#t16;
+ } =>#t15;
block {
- final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t20 = m;
- if(!#t20.{core::Object::==}(null)) {
- core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t20{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+ final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t19 = m;
+ if(!#t19.{core::Object::==}(null)) {
+ core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t19{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::MapEntry<core::String, core::int> #t21 = :sync-for-iterator.{core::Iterator::current};
- #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
+ final core::MapEntry<core::String, core::int> #t20 = :sync-for-iterator.{core::Iterator::current};
+ #t18.{core::Map::[]=}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
}
}
- } =>#t19;
+ } =>#t18;
s!;
- let final core::String #t22 = s in #t22.{core::String::==}(null) ?{core::String?} null : #t22.{core::String::substring}(0, 0);
- let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = 42;
- let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length} = #t24.{core::List::length}.{core::num::+}(42);
- let final core::List<core::String> #t25 = l in #t25.{core::List::==}(null) ?{core::int?} null : #t25.{core::List::length}.{core::num::==}(null) ?{core::int} #t25.{core::List::length} = 42 : null;
- let final core::String #t26 = s in #t26.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t26);
- let final core::String #t27 = s in let final core::int #t28 = 42 in self::E|[](#t27, #t28).{core::num::==}(null) ?{core::int} self::E|[]=(#t27, #t28, 42) : null;
- let final core::List<core::String> #t29 = l in let final core::int #t30 = 42 in #t29.{core::List::[]}(#t30).{core::String::==}(null) ?{core::String} #t29.{core::List::[]=}(#t30, "foo") : null;
- let final core::List<core::String> #t31 = l in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
- let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t33 = #t32.{core::List::length} = 42 in #t32;
- let final core::List<core::String> #t34 = l in #t34.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t35 = let final core::List<core::String> #t36 = #t34 in #t36.{core::List::length}.{core::num::==}(null) ?{core::int} #t36.{core::List::length} = 42 : null in #t34;
+ let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
+ let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
+ let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
+ let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
+ let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
+ let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
+ let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
+ let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
+ let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ #t31.{core::List::length} = 42;
+ } =>#t31;
+ let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
+ } =>#t32;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
index 5f0452d..ea9d20e 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.expect
@@ -132,56 +132,62 @@
return 42;
static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
- let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : let final void #t4 = #t3.{core::String::length} in #t3;
- let final core::String #t5 = s in #t5.{core::String::==}(null) ?{core::String} "foo" : #t5;
+ let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : block {
+ #t3.{core::String::length};
+ } =>#t3;
+ let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
s.{core::String::==}(null) ?{core::String} s = "foo" : null;
block {
- final core::List<core::String> #t6 = <core::String>[];
- final core::Iterable<core::String>? #t7 = l;
- if(!#t7.{core::Object::==}(null))
- for (final core::String #t8 in #t7{core::Iterable<core::String>})
- #t6.{core::List::add}(#t8);
- } =>#t6;
+ final core::List<core::String> #t5 = <core::String>[];
+ final core::Iterable<core::String>? #t6 = l;
+ if(!#t6.{core::Object::==}(null))
+ for (final core::String #t7 in #t6{core::Iterable<core::String>})
+ #t5.{core::List::add}(#t7);
+ } =>#t5;
core::Set<core::String> a = block {
- final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t10 = l;
- if(!#t10.{core::Object::==}(null))
- for (final dynamic #t11 in #t10{core::Iterable<core::String>}) {
- final core::String #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::String;
- #t9.{core::Set::add}(#t12);
+ final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t9 = l;
+ if(!#t9.{core::Object::==}(null))
+ for (final dynamic #t10 in #t9{core::Iterable<core::String>}) {
+ final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
+ #t8.{core::Set::add}(#t11);
}
- } =>#t9;
+ } =>#t8;
block {
- final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t14 = l;
- if(!#t14.{core::Object::==}(null))
- for (final core::String #t15 in #t14{core::Iterable<core::String>})
- #t13.{core::Set::add}(#t15);
- } =>#t13;
+ final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t13 = l;
+ if(!#t13.{core::Object::==}(null))
+ for (final core::String #t14 in #t13{core::Iterable<core::String>})
+ #t12.{core::Set::add}(#t14);
+ } =>#t12;
core::Map<core::String, core::int> b = block {
- final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t17 = m;
- if(!#t17.{core::Object::==}(null))
- for (final core::MapEntry<core::String, core::int> #t18 in #t17{core::Map<core::String, core::int>}.{core::Map::entries})
- #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
- } =>#t16;
+ final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t16 = m;
+ if(!#t16.{core::Object::==}(null))
+ for (final core::MapEntry<core::String, core::int> #t17 in #t16{core::Map<core::String, core::int>}.{core::Map::entries})
+ #t15.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
+ } =>#t15;
block {
- final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t20 = m;
- if(!#t20.{core::Object::==}(null))
- for (final core::MapEntry<core::String, core::int> #t21 in #t20{core::Map<core::String, core::int>}.{core::Map::entries})
- #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
- } =>#t19;
+ final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t19 = m;
+ if(!#t19.{core::Object::==}(null))
+ for (final core::MapEntry<core::String, core::int> #t20 in #t19{core::Map<core::String, core::int>}.{core::Map::entries})
+ #t18.{core::Map::[]=}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
+ } =>#t18;
s!;
- let final core::String #t22 = s in #t22.{core::String::==}(null) ?{core::String?} null : #t22.{core::String::substring}(0, 0);
- let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = 42;
- let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length} = #t24.{core::List::length}.{core::num::+}(42);
- let final core::List<core::String> #t25 = l in #t25.{core::List::==}(null) ?{core::int?} null : #t25.{core::List::length}.{core::num::==}(null) ?{core::int} #t25.{core::List::length} = 42 : null;
- let final core::String #t26 = s in #t26.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t26);
- let final core::String #t27 = s in let final core::int #t28 = 42 in self::E|[](#t27, #t28).{core::num::==}(null) ?{core::int} self::E|[]=(#t27, #t28, 42) : null;
- let final core::List<core::String> #t29 = l in let final core::int #t30 = 42 in #t29.{core::List::[]}(#t30).{core::String::==}(null) ?{core::String} #t29.{core::List::[]=}(#t30, "foo") : null;
- let final core::List<core::String> #t31 = l in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
- let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t33 = #t32.{core::List::length} = 42 in #t32;
- let final core::List<core::String> #t34 = l in #t34.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t35 = let final core::List<core::String> #t36 = #t34 in #t36.{core::List::length}.{core::num::==}(null) ?{core::int} #t36.{core::List::length} = 42 : null in #t34;
+ let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
+ let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
+ let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
+ let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
+ let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
+ let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
+ let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
+ let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
+ let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ #t31.{core::List::length} = 42;
+ } =>#t31;
+ let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
+ } =>#t32;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
index 2e60ba3..301af59 100644
--- a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.weak.transformed.expect
@@ -132,77 +132,83 @@
return 42;
static method warning(core::String s, core::List<core::String> l, core::Map<core::String, core::int> m) → dynamic {
let final core::String #t2 = s in #t2.{core::String::==}(null) ?{core::int?} null : #t2.{core::String::length};
- let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : let final void #t4 = #t3.{core::String::length} in #t3;
- let final core::String #t5 = s in #t5.{core::String::==}(null) ?{core::String} "foo" : #t5;
+ let final core::String #t3 = s in #t3.{core::String::==}(null) ?{core::String} null : block {
+ #t3.{core::String::length};
+ } =>#t3;
+ let final core::String #t4 = s in #t4.{core::String::==}(null) ?{core::String} "foo" : #t4;
s.{core::String::==}(null) ?{core::String} s = "foo" : null;
block {
- final core::List<core::String> #t6 = <core::String>[];
- final core::Iterable<core::String>? #t7 = l;
- if(!#t7.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t7{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::List<core::String> #t5 = <core::String>[];
+ final core::Iterable<core::String>? #t6 = l;
+ if(!#t6.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t6{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::String #t8 = :sync-for-iterator.{core::Iterator::current};
- #t6.{core::List::add}(#t8);
+ final core::String #t7 = :sync-for-iterator.{core::Iterator::current};
+ #t5.{core::List::add}(#t7);
}
}
- } =>#t6;
+ } =>#t5;
core::Set<core::String> a = block {
- final core::Set<core::String> #t9 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t10 = l;
- if(!#t10.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t10{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::Set<core::String> #t8 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t9 = l;
+ if(!#t9.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t9{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final dynamic #t11 = :sync-for-iterator.{core::Iterator::current};
+ final dynamic #t10 = :sync-for-iterator.{core::Iterator::current};
{
- final core::String #t12 = #t11 as{TypeError,ForNonNullableByDefault} core::String;
- #t9.{core::Set::add}(#t12);
+ final core::String #t11 = #t10 as{TypeError,ForNonNullableByDefault} core::String;
+ #t8.{core::Set::add}(#t11);
}
}
}
- } =>#t9;
+ } =>#t8;
block {
- final core::Set<core::String> #t13 = col::LinkedHashSet::•<core::String>();
- final core::Iterable<core::String>? #t14 = l;
- if(!#t14.{core::Object::==}(null)) {
- core::Iterator<core::String> :sync-for-iterator = #t14{core::Iterable<core::String>}.{core::Iterable::iterator};
+ final core::Set<core::String> #t12 = col::LinkedHashSet::•<core::String>();
+ final core::Iterable<core::String>? #t13 = l;
+ if(!#t13.{core::Object::==}(null)) {
+ core::Iterator<core::String> :sync-for-iterator = #t13{core::Iterable<core::String>}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::String #t15 = :sync-for-iterator.{core::Iterator::current};
- #t13.{core::Set::add}(#t15);
+ final core::String #t14 = :sync-for-iterator.{core::Iterator::current};
+ #t12.{core::Set::add}(#t14);
}
}
- } =>#t13;
+ } =>#t12;
core::Map<core::String, core::int> b = block {
- final core::Map<core::String, core::int> #t16 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t17 = m;
- if(!#t17.{core::Object::==}(null)) {
- core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t17{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+ final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t16 = m;
+ if(!#t16.{core::Object::==}(null)) {
+ core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t16{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::MapEntry<core::String, core::int> #t18 = :sync-for-iterator.{core::Iterator::current};
- #t16.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
+ final core::MapEntry<core::String, core::int> #t17 = :sync-for-iterator.{core::Iterator::current};
+ #t15.{core::Map::[]=}(#t17.{core::MapEntry::key}, #t17.{core::MapEntry::value});
}
}
- } =>#t16;
+ } =>#t15;
block {
- final core::Map<core::String, core::int> #t19 = <core::String, core::int>{};
- final core::Map<core::String, core::int>? #t20 = m;
- if(!#t20.{core::Object::==}(null)) {
- core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t20{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
+ final core::Map<core::String, core::int> #t18 = <core::String, core::int>{};
+ final core::Map<core::String, core::int>? #t19 = m;
+ if(!#t19.{core::Object::==}(null)) {
+ core::Iterator<core::MapEntry<core::String, core::int>> :sync-for-iterator = #t19{core::Map<core::String, core::int>}.{core::Map::entries}.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::MapEntry<core::String, core::int> #t21 = :sync-for-iterator.{core::Iterator::current};
- #t19.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
+ final core::MapEntry<core::String, core::int> #t20 = :sync-for-iterator.{core::Iterator::current};
+ #t18.{core::Map::[]=}(#t20.{core::MapEntry::key}, #t20.{core::MapEntry::value});
}
}
- } =>#t19;
+ } =>#t18;
s!;
- let final core::String #t22 = s in #t22.{core::String::==}(null) ?{core::String?} null : #t22.{core::String::substring}(0, 0);
- let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = 42;
- let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length} = #t24.{core::List::length}.{core::num::+}(42);
- let final core::List<core::String> #t25 = l in #t25.{core::List::==}(null) ?{core::int?} null : #t25.{core::List::length}.{core::num::==}(null) ?{core::int} #t25.{core::List::length} = 42 : null;
- let final core::String #t26 = s in #t26.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t26);
- let final core::String #t27 = s in let final core::int #t28 = 42 in self::E|[](#t27, #t28).{core::num::==}(null) ?{core::int} self::E|[]=(#t27, #t28, 42) : null;
- let final core::List<core::String> #t29 = l in let final core::int #t30 = 42 in #t29.{core::List::[]}(#t30).{core::String::==}(null) ?{core::String} #t29.{core::List::[]=}(#t30, "foo") : null;
- let final core::List<core::String> #t31 = l in #t31.{core::List::length}.{core::num::==}(null) ?{core::int} #t31.{core::List::length} = 42 : null;
- let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t33 = #t32.{core::List::length} = 42 in #t32;
- let final core::List<core::String> #t34 = l in #t34.{core::List::==}(null) ?{core::List<core::String>} null : let final void #t35 = let final core::List<core::String> #t36 = #t34 in #t36.{core::List::length}.{core::num::==}(null) ?{core::int} #t36.{core::List::length} = 42 : null in #t34;
+ let final core::String #t21 = s in #t21.{core::String::==}(null) ?{core::String?} null : #t21.{core::String::substring}(0, 0);
+ let final core::List<core::String> #t22 = l in #t22.{core::List::==}(null) ?{core::int?} null : #t22.{core::List::length} = 42;
+ let final core::List<core::String> #t23 = l in #t23.{core::List::==}(null) ?{core::int?} null : #t23.{core::List::length} = #t23.{core::List::length}.{core::num::+}(42);
+ let final core::List<core::String> #t24 = l in #t24.{core::List::==}(null) ?{core::int?} null : #t24.{core::List::length}.{core::num::==}(null) ?{core::int} #t24.{core::List::length} = 42 : null;
+ let final core::String #t25 = s in #t25.{core::String::==}(null) ?{core::int?} null : self::E|get#foo(#t25);
+ let final core::String #t26 = s in let final core::int #t27 = 42 in self::E|[](#t26, #t27).{core::num::==}(null) ?{core::int} self::E|[]=(#t26, #t27, 42) : null;
+ let final core::List<core::String> #t28 = l in let final core::int #t29 = 42 in #t28.{core::List::[]}(#t29).{core::String::==}(null) ?{core::String} #t28.{core::List::[]=}(#t29, "foo") : null;
+ let final core::List<core::String> #t30 = l in #t30.{core::List::length}.{core::num::==}(null) ?{core::int} #t30.{core::List::length} = 42 : null;
+ let final core::List<core::String> #t31 = l in #t31.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ #t31.{core::List::length} = 42;
+ } =>#t31;
+ let final core::List<core::String> #t32 = l in #t32.{core::List::==}(null) ?{core::List<core::String>} null : block {
+ let final core::List<core::String> #t33 = #t32 in #t33.{core::List::length}.{core::num::==}(null) ?{core::int} #t33.{core::List::length} = 42 : null;
+ } =>#t32;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
index f5cfaf9..8dc052e 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.expect
@@ -33,8 +33,10 @@
late core::int local = 42;
core::String? s = null;
dynamic c;
- let final dynamic #t1 = c in #t1.{core::Object::==}(null) ?{dynamic} null : let final void #t2 = #t1.f in #t1;
- let final dynamic #t3 = c in #t3.{core::Object::==}(null) ?{dynamic} null : #t3.[](0);
+ let final dynamic #t1 = c in #t1.{core::Object::==}(null) ?{dynamic} null : block {
+ #t1.f;
+ } =>#t1;
+ let final dynamic #t2 = c in #t2.{core::Object::==}(null) ?{dynamic} null : #t2.[](0);
}
library;
diff --git a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
index f5cfaf9..8dc052e 100644
--- a/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/opt_out.dart.weak.transformed.expect
@@ -33,8 +33,10 @@
late core::int local = 42;
core::String? s = null;
dynamic c;
- let final dynamic #t1 = c in #t1.{core::Object::==}(null) ?{dynamic} null : let final void #t2 = #t1.f in #t1;
- let final dynamic #t3 = c in #t3.{core::Object::==}(null) ?{dynamic} null : #t3.[](0);
+ let final dynamic #t1 = c in #t1.{core::Object::==}(null) ?{dynamic} null : block {
+ #t1.f;
+ } =>#t1;
+ let final dynamic #t2 = c in #t2.{core::Object::==}(null) ?{dynamic} null : #t2.[](0);
}
library;
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.strong.expect b/pkg/front_end/testcases/rasta/cascades.dart.strong.expect
index 5c396a9..af9230d 100644
--- a/pkg/front_end/testcases/rasta/cascades.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/cascades.dart.strong.expect
@@ -23,5 +23,7 @@
self::A* a = new self::A::•();
function f(dynamic x) → dynamic
return x;
- let final self::A* #t1 = a in let final void #t2 = #t1.{self::A::add}(f).call("WHAT") in #t1;
+ let final self::A* #t1 = a in block {
+ #t1.{self::A::add}(f).call("WHAT");
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/cascades.dart.strong.transformed.expect
index 5c396a9..af9230d 100644
--- a/pkg/front_end/testcases/rasta/cascades.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/cascades.dart.strong.transformed.expect
@@ -23,5 +23,7 @@
self::A* a = new self::A::•();
function f(dynamic x) → dynamic
return x;
- let final self::A* #t1 = a in let final void #t2 = #t1.{self::A::add}(f).call("WHAT") in #t1;
+ let final self::A* #t1 = a in block {
+ #t1.{self::A::add}(f).call("WHAT");
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
index 8b4190c..10e6c4d 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
@@ -14,5 +14,7 @@
static method main() → dynamic {
let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
math..toString();
- ^^^^" in let final void #t2 = #t1.{core::Object::toString}() in #t1;
+ ^^^^" in block {
+ #t1.{core::Object::toString}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
index 8b4190c..10e6c4d 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
@@ -14,5 +14,7 @@
static method main() → dynamic {
let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
math..toString();
- ^^^^" in let final void #t2 = #t1.{core::Object::toString}() in #t1;
+ ^^^^" in block {
+ #t1.{core::Object::toString}();
+ } =>#t1;
}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 288ca73..6fec5fe 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -139,6 +139,8 @@
late_lowering/issue40373b: FormatterCrash
late_lowering/issue40805: FormatterCrash
late_lowering/issue41436b: FormatterCrash
+late_lowering/issue41922: FormatterCrash
+late_lowering/late_annotations: FormatterCrash
late_lowering/late_field_inference: FormatterCrash
late_lowering/late_field_with_initializer: FormatterCrash
late_lowering/late_field_without_initializer: FormatterCrash
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b778934..7a8b245 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -466,6 +466,9 @@
List<int> index = <int>[];
while (_byteOffset > 0) {
int size = readUint32();
+ if (size <= 0) {
+ throw fail("invalid size '$size' reported at offset $byteOffset");
+ }
int start = _byteOffset - size;
if (start < 0) {
throw fail("indicated size does not match file size");
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 78cd33e..4a5614a 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -75,7 +75,7 @@
TreeNode currentParent;
- TreeNode get context => currentMember ?? currentClass;
+ TreeNode get currentClassOrMember => currentMember ?? currentClass;
static void check(Component component, {bool isOutline, bool afterConst}) {
component.accept(
@@ -104,7 +104,7 @@
}
problem(TreeNode node, String details, {TreeNode context}) {
- context ??= this.context;
+ context ??= currentClassOrMember;
throw new VerificationError(context, node, details);
}
diff --git a/pkg/kernel/test/binary/invalid_index_size.dart b/pkg/kernel/test/binary/invalid_index_size.dart
new file mode 100644
index 0000000..46f9bc4
--- /dev/null
+++ b/pkg/kernel/test/binary/invalid_index_size.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/binary/ast_from_binary.dart' show ParseError;
+
+import 'utils.dart';
+
+main() {
+ Library lib1 = new Library(Uri.parse("foo://bar.dart"));
+ Component c1 = new Component(libraries: [lib1]);
+ List<int> serialized = serializeComponent(c1);
+ // The last 4 bytes is the size entry in the index. Overwrite that with 0's.
+ for (int i = serialized.length - 4; i < serialized.length; i++) {
+ serialized[i] = 0;
+ }
+ bool gotExpectedException = false;
+ try {
+ loadComponentFromBytes(serialized);
+ throw "The above line should have thrown.";
+ } on ParseError catch (e) {
+ if (e.toString().contains("invalid size")) {
+ gotExpectedException = true;
+ }
+ }
+ if (!gotExpectedException) {
+ throw "Didn't get the right exception!";
+ }
+}
diff --git a/pkg/nnbd_migration/README.md b/pkg/nnbd_migration/README.md
index 4e46dd6..f777eee 100644
--- a/pkg/nnbd_migration/README.md
+++ b/pkg/nnbd_migration/README.md
@@ -1,85 +1,138 @@
# Null Safety Migration Tooling
-Note: the null safety migration tooling and workflow is in an early state;
-this doc will be updated as the steps and workflow are simplified.
+Note: the null safety migration tooling is in an early state and may have bugs
+and other issues.
-## Building the NNBD sdk
+For best results, use SDK version 2.9.0-10.0.dev or higher.
-In order to run the tool currently you have to be able to build your own copy
-of the Dart SDK.
+## How Migration Works
-To do this, run:
+The migration uses a _new interactive algorithm_ designed specifically for Dart
+null safety.
-```
-./tools/build.py -mrelease --nnbd create_sdk
+Typical code migration tools are designed to be run once, handle most cases, and
+let the developer do manual cleanup on the result. This does **not work well**
+for Null-Safety and attempting this workflow will result in a lot more manual
+work. Similarly, after your migration has been applied, the migration **cannot
+be rerun** without first reverting it.
+
+### Why does the interactive approach save so much time?
+
+Remember that Dart already has nullable types. Every type in old Dart code is
+nullable! What old Dart lacks is _non-null_ types.
+
+And like most migrations, our tool tries to preserve your code's current
+behavior. In the case of null safety, we may mark a lot of your types as
+nullable -- because they really were nullable before.
+
+Nulls are traced through your program as far as they can go, and types are
+marked nullable in this process. If the tool makes a single mistake or choice
+you disagree with, it can lead many excess nullable types.
+
+### Interactive feedback to the tool
+
+Unintentional null is the top cause of crashes in Dart programs. By marking your
+intention with comments like `/*?*/` and `/*!*/`, we can stop these
+unintentional nulls from spreading through your program in your migrated code.
+Adding a small number of these hints will have a huge impact on migration
+quality.
+
+The high level workflow of the tool is therefore driven through an interactive
+web UI. After running `dart migrate`, open the resulting url in a browser. Scan
+through the changes, use the "nullability trace" feature to find the best place
+to add a nullability hint (adding a hint in the best place can prevent dozens of
+types from being made nullable). Rerun the migration and repeat, committing the
+hints as you go. When the output is correct and acceptable, apply the migration
+and publish your null safe code!
+
+For example,
+
+```dart
+List<int> ints = const [0, null];
+int zero = ints[0];
+int one = zero + 1;
+List<int> zeroOne = [zero, one];
```
-The NNBD sdk now lives under the ReleaseX64NNBD sub-directory of your build
-directory, e.g.
+The default migration will be backwards compatible, but not ideal.
+```dart
+List<int?> ints = const [0, null];
+int? zero = ints[0];
+int one = zero! + 1;
+List<int?> zeroOne = <int?>[zero, one];
```
-xcodebuild/ReleaseX64NNBD/dart-sdk/
+
+`zero` should not be marked nullable, but it is. We then have cascading quality
+issues, such as null-checking a value that shouldn't have been marked null, and
+marking other variables as null due to deep null tracing. We can fix this all by
+adding a single `/*!*/` hint.
+
+```dart
+List<int?> ints = const [0, null];
+int/*?*/ zero = ints[0]!; // Just add /*?*/ here, the migration tool does the rest!
+int one = zero + 1;
+List<int> zeroOne = <int>[zero, one];
```
+If you add one hint before migrating, you have done the equivalent of making
+five manual edits after migrating. To find the best place to put your hints, use
+the preview tool's nullability trace feature. This lets you trace back up to the
+root cause of any type's inferred nullability. Add hints as close to the
+original source of null as possible to have the biggest impact to the migration.
+
+**Note**: The migration tool **cannot be rerun on a migrated codebase.** At
+that point in time, every nullable and non-nullable type is indistinguishable
+from an **intentionally** nullable or non-nullable type. The opportunity to
+change large numbers of types for you at once without also accidentally changing
+your intent has been lost. A long migration effort (such as one on a large
+project) can be done incrementally, by committing these hints over time.
+
## Migrating a package
-- build a NNBD version of the SDK (see above)
- select a package to work on
-- in that package, edit the `analysis_options.yaml` to enable the NNBD
- experiment from the POV of the analyzer:
-```yaml
-analyzer:
- enable-experiment:
- - non-nullable
-```
-- run `pub get` for the package (and, verify that the
- `.dart_tool/package_config.json` file was created)
+- run `pub get` for the package
Then, run the migration tool from the top-level of the package directory:
```
-<sdk-repo>/xcodebuild/ReleaseX64NNBD/dart migrate .
+dart migrate
```
-The migration tool will run, print the proposed changes to the console, and
-display a url for the preview tool. Open that url from a browser to see a rich
-preview of the proposed null safety changes.
+The migration tool will run and display a url for the web UI. Open that url from
+a browser to view, analyze, and improve the proposed null-safe migration.
## Using the tool
1. Run the tool (see above).
-2. Once analysis and migration suggestions are complete, open the indicated url
-in a browser.
-3. Start with an important or interesting file in your package on the left
-side by clicking on it.
+2. Once analysis and migration is complete, open the indicated url in a browser.
+3. Start with an important or interesting file in your package on the left side
+ by clicking on it.
4. Look at the proposed edits in the upper right, and click on them in turn.
5. If you see an edit that looks wrong:
1. Use the "trace view" in the bottom right to find the root cause
- 2. Go to your editor and make a change to the original file by adding a hint
- (`String foo` ==> `String/*!*/ foo`) or making other changes as needed.
- 3. You can have the migration tool perform this itself, although right now
- for large packages this takes a prohibitively long time.
- 1. ***Warning: DO NOT mix edits in your editor and edits applied by the
- migration tool. We have not yet written the necessary logic to
- prevent the migration tool from clobbering files edited while the
- preview tool is running.***
- 2. To try this, from the 'Edit Details' area in the bottom right select
- the `Force type to be non-nullable` or `Force type to be nullable`
- links. These will add the indicated hints on disk and recompute the
- migration suggestions.
-6. After some edits are complete, control-C the migration and rerun it. If
-some things are still wrong, return to step 5.
-7. Once all edits are complete and you've rerun migration and are satisfied with
-the output:
+ 2. Either click on an "add hint" button to correct it at the root, or open
+ your editor and make the change manually.
+ 1. Some changes are as simple as adding a `/*!*/` hint on a type. The
+ tool has buttons to do this for you.
+ 2. Others may require larger refactors. These changes can be made in
+ your editor, and may often be committed and published immediately.
+ 3. Periodically rerun the migration and repeat.
+6. Once you are satisfied with the proposed migration:
1. Save your work using git or other means. Applying the migration will
- overwrite the existing files on disk.
- 2. Rerun the migration with `--apply-changes`, or click the
- `Apply Migration` button in the interface.
-8. Remove any SDK constraint in your pubspec.yaml.
-9. Remove any opt-out comments in your library files (e.g.: `// @dart = 2.6`).
-10. Rerun `pub get` and test your package.
+ overwrite the existing files on disk.
+ 2. Rerun the migration by clicking the `Apply Migration` button in the
+ interface.
+ 3. Tip: leaving the web UI open may help you if you later have test failures
+ or analysis errors.
+7. Rerun `pub get` and test your package.
+ 1. If a test fails, you may still use the preview to help you figure out
+ what went wrong.
+ 2. If large changes are required, revert the migration, and go back to step
+ one.
+8. Commit and/or publish your migrated null-safe code
## Providing feedback
Please file issues at https://github.com/dart-lang/sdk/issues, and reference the
-`analyzer-nnbd-migration` label (you may not be able to apply the label yourself).
+`analyzer-nnbd-migration` label (you may not be able to apply the label yourself).
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 88df6f6..a313f3c 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert' show jsonDecode;
import 'dart:io' hide File;
import 'package:analyzer/dart/analysis/results.dart';
@@ -46,6 +47,7 @@
static const ignoreErrorsFlag = 'ignore-errors';
static const previewPortOption = 'preview-port';
static const sdkPathOption = 'sdk-path';
+ static const skipPubOutdatedFlag = 'skip-pub-outdated';
static const summaryOption = 'summary';
static const verboseFlag = 'verbose';
static const webPreviewFlag = 'web-preview';
@@ -60,6 +62,8 @@
final String sdkPath;
+ final bool skipPubOutdated;
+
final String summary;
final bool webPreview;
@@ -70,10 +74,103 @@
@required this.ignoreErrors,
@required this.previewPort,
@required this.sdkPath,
+ @required this.skipPubOutdated,
@required this.summary,
@required this.webPreview});
}
+@visibleForTesting
+class DependencyChecker {
+ final Context _pathContext;
+ final Logger _logger;
+ final ProcessManager _processManager;
+
+ DependencyChecker(this._pathContext, this._logger, this._processManager);
+
+ bool check() {
+ var pubPath = _pathContext.join(getSdkPath(), 'bin', 'pub');
+ var result = _processManager
+ .runSync(pubPath, ['outdated', '--mode=null-safety', '--json']);
+
+ var preNullSafetyPackages = <String, String>{};
+ try {
+ if ((result.stderr as String).isNotEmpty) {
+ throw FormatException(
+ '`pub outdated --mode=null-safety` exited with exit code '
+ '${result.exitCode} and stderr:\n\n${result.stderr}');
+ }
+ var outdatedOutput = jsonDecode(result.stdout as String);
+ var outdatedMap = _expectType<Map>(outdatedOutput, 'root');
+ var packageList = _expectType<List>(outdatedMap['packages'], 'packages');
+ for (var package_ in packageList) {
+ var package = _expectType<Map>(package_, '');
+ var current_ = _expectKey(package, 'current');
+ if (current_ == null) {
+ continue;
+ }
+ var current = _expectType<Map>(current_, 'current');
+ if (_expectType<bool>(current['nullSafety'], 'nullSafety')) {
+ // For whatever reason, there is no "current" version of this package.
+ // TODO(srawlins): We may want to report this to the user. But it may
+ // be inconsequential.
+ continue;
+ }
+
+ _expectKey(package, 'package');
+ _expectKey(current, 'version');
+ var name = _expectType<String>(package['package'], 'package');
+ // A version will be given, even if a package was provided with a local
+ // or git path.
+ var version = _expectType<String>(current['version'], 'version');
+ preNullSafetyPackages[name] = version;
+ }
+ } on FormatException catch (e) {
+ _logger.stderr('Warning: ${e.message}');
+ // Allow the program to continue; users should be allowed to attempt to
+ // migrate when `pub outdated` is misbehaving, or if there is a bug above.
+ }
+ if (preNullSafetyPackages.isNotEmpty) {
+ _logger.stderr(
+ 'Warning: dependencies are outdated. The version(s) of one or more '
+ 'packages currently checked out have not yet migrated to the Null '
+ 'Safety feature.');
+ _logger.stderr('');
+ for (var package in preNullSafetyPackages.entries) {
+ _logger.stderr(
+ ' ${package.key}, currently at version ${package.value}');
+ }
+ _logger.stderr('');
+ _logger.stderr('It is highly recommended to upgrade all dependencies to '
+ 'versions which have migrated. Use `pub outdated --mode=null-safety` '
+ 'to check the status of dependencies. Visit '
+ 'https://dart.dev/tools/pub/cmd/pub-outdated for more information.');
+ _logger.stderr('');
+ _logger.stderr('Force migration with --skip-outdated-dependencies-check '
+ '(not recommended)');
+ return false;
+ }
+ return true;
+ }
+
+ dynamic _expectKey(Map<Object, Object> map, String key) {
+ if (map.containsKey(key)) {
+ return map[key];
+ }
+ throw FormatException(
+ 'Unexpected `pub outdated` JSON output: missing key ($key)', map);
+ }
+
+ T _expectType<T>(Object object, String errorKey) {
+ if (object is T) {
+ return object;
+ }
+ throw FormatException(
+ 'Unexpected `pub outdated` JSON output: expected a '
+ '$T at "$errorKey", but got a ${object.runtimeType}',
+ object);
+ }
+}
+
class MigrateCommand extends Command<dynamic> {
final bool verbose;
@@ -118,6 +215,11 @@
/// user. Used in testing to allow user feedback messages to be tested.
final Logger Function(bool isVerbose) loggerFactory;
+ /// Process manager that should be used to run processes. Used in testing to
+ /// redirect to mock processes.
+ @visibleForTesting
+ final ProcessManager processManager;
+
/// Resource provider that should be used to access the filesystem. Used in
/// testing to redirect to an in-memory filesystem.
final ResourceProvider resourceProvider;
@@ -145,7 +247,8 @@
{@required this.binaryName,
@visibleForTesting this.loggerFactory = _defaultLoggerFactory,
@visibleForTesting this.defaultSdkPathOverride,
- @visibleForTesting ResourceProvider resourceProvider})
+ @visibleForTesting ResourceProvider resourceProvider,
+ @visibleForTesting this.processManager = const ProcessManager.system()})
: logger = loggerFactory(false),
resourceProvider =
resourceProvider ?? PhysicalResourceProvider.INSTANCE;
@@ -217,6 +320,8 @@
sdkPath: argResults[CommandLineOptions.sdkPathOption] as String ??
defaultSdkPathOverride ??
getSdkPath(),
+ skipPubOutdated:
+ argResults[CommandLineOptions.skipPubOutdatedFlag] as bool,
summary: argResults[CommandLineOptions.summaryOption] as String,
webPreview: webPreview);
if (isVerbose) {
@@ -247,6 +352,10 @@
void run(ArgResults argResults, {bool isVerbose}) async {
decodeCommandLineArgs(argResults, isVerbose: isVerbose);
if (exitCode != null) return;
+ if (!options.skipPubOutdated) {
+ _checkDependencies();
+ }
+ if (exitCode != null) return;
logger.stdout('Migrating ${options.directory}');
logger.stdout('');
@@ -370,6 +479,14 @@
}
}
+ void _checkDependencies() {
+ var successful =
+ DependencyChecker(pathContext, logger, processManager).check();
+ if (!successful) {
+ exitCode = 1;
+ }
+ }
+
void _checkForErrors() {
if (fileErrors.isEmpty) {
logger.stdout('No analysis issues found.');
@@ -545,6 +662,12 @@
'dynamically allocate a port.');
parser.addOption(CommandLineOptions.sdkPathOption,
help: 'The path to the Dart SDK.', hide: hide);
+ parser.addFlag(
+ CommandLineOptions.skipPubOutdatedFlag,
+ defaultsTo: false,
+ negatable: false,
+ help: 'Skip the `pub outdated --mode=null-safety` check.',
+ );
parser.addOption(CommandLineOptions.summaryOption,
help:
'Output path for a machine-readable summary of migration changes');
@@ -571,6 +694,25 @@
}
}
+/// An abstraction over the static methods on [Process].
+///
+/// Used in tests to run mock processes.
+abstract class ProcessManager {
+ const factory ProcessManager.system() = SystemProcessManager;
+
+ /// Run a process synchronously, as in [Process.runSync].
+ ProcessResult runSync(String executable, List<String> arguments);
+}
+
+/// A [ProcessManager] that directs all method calls to static methods of
+/// [Process], in order to run real processes.
+class SystemProcessManager implements ProcessManager {
+ const SystemProcessManager();
+
+ ProcessResult runSync(String executable, List<String> arguments) =>
+ Process.runSync(executable, arguments);
+}
+
class _BadArgException implements Exception {
final String message;
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index ee0201b..e9c3f1d 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -226,7 +226,9 @@
if (targetType != null) {
var enclosingElement = baseElement.enclosingElement;
if (enclosingElement is ClassElement) {
- if (enclosingElement.typeParameters.isNotEmpty) {
+ if (targetType.type.resolveToBound(typeProvider.dynamicType)
+ is InterfaceType &&
+ enclosingElement.typeParameters.isNotEmpty) {
substitution = _decoratedClassHierarchy
.asInstanceOf(targetType, enclosingElement)
.asSubstitution;
@@ -968,7 +970,7 @@
@override
DecoratedType visitInstanceCreationExpression(
InstanceCreationExpression node) {
- var callee = node.staticElement;
+ var callee = node.constructorName.staticElement;
var typeParameters = callee.enclosingElement.typeParameters;
Iterable<DartType> typeArgumentTypes;
List<DecoratedType> decoratedTypeArguments;
@@ -1463,7 +1465,7 @@
} else if (staticElement is ExtensionElement) {
result = _makeNonNullLiteralType(node);
} else if (staticElement == null) {
- assert(node.toString() == 'void');
+ assert(node.toString() == 'void', "${node.toString()} != 'void'");
result = _makeNullableVoidType(node);
} else if (staticElement.enclosingElement is ClassElement &&
(staticElement.enclosingElement as ClassElement).isEnum) {
@@ -2722,10 +2724,9 @@
method.enclosingElement is ExtensionElement) {
// Extension methods can be called on a `null` target, when the `on` type
// of the extension is nullable.
- _handleAssignment(target,
+ return _handleAssignment(target,
destinationType:
_variables.decoratedElementType(method.enclosingElement));
- return _dispatch(target);
} else {
return _checkExpressionNotNull(target);
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
index 8f62adb..7774927 100644
--- a/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/migration_info.dart
@@ -6,7 +6,6 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
-import 'package:meta/meta.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 29d4359..6047aa9 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -3371,6 +3371,22 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_is_promotion_implies_non_nullable_generic() async {
+ var content = '''
+int f<T>(T o) => o is List ? o.length : 0;
+main() {
+ f(null);
+}
+''';
+ var expected = '''
+int f<T>(T o) => o is List ? o.length : 0;
+main() {
+ f(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_isExpression_typeName_typeArguments() async {
var content = '''
bool f(a) => a is List<int>;
@@ -3869,6 +3885,28 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_methodInvocation_extension_invocation() async {
+ var content = '''
+extension on bool {
+ void f() {}
+}
+bool g<T>(T x) => true;
+void main() {
+ g<int>(null).f();
+}
+''';
+ var expected = '''
+extension on bool {
+ void f() {}
+}
+bool g<T>(T x) => true;
+void main() {
+ g<int?>(null).f();
+}
+''';
+ await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+ }
+
Future<void> test_methodInvocation_typeArguments_explicit() async {
var content = '''
T f<T>(T t) => t;
@@ -5343,6 +5381,42 @@
await _checkSingleFileChanges(content, expected);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
+ Future<void> test_this_inside_extension() async {
+ var content = '''
+class C<T> {
+ T field;
+}
+extension on C<int> {
+ f() {
+ this.field = null;
+ }
+}
+extension on C<List<int>> {
+ f() {
+ this.field = null;
+ }
+}
+''';
+ var expected = '''
+
+class C<T> {
+ T field;
+}
+extension on C<int?> {
+ f() {
+ this.field = null;
+ }
+}
+extension on C<List<int?>> {
+ f() {
+ this.field = [null];
+ }
+}
+''';
+ await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
+ }
+
Future<void> test_topLevelFunction_parameterType_implicit_dynamic() async {
var content = '''
Object f(x) => x;
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 95c3ce0..c4825b1 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2907,6 +2907,31 @@
// metadata was visited.
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
+ Future<void> test_extension_on_class_with_generic_type_arguments() async {
+ await analyze('''
+class C<T> {}
+void f(C<List> x) {}
+extension E on C<List> {
+ g() => f(this);
+}
+''');
+ // No assertions yet. This test crashes. When it stops crashing, consider
+ // adding assertion(s).
+ }
+
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39387')
+ Future<void> test_extension_on_function_type() async {
+ await analyze('''
+extension CurryFunction<R, S, T> on R Function(S, T) {
+ /// Curry a binary function with its first argument.
+ R Function(T) curry(S first) => (T second) => this(first, second);
+}
+''');
+ // No assertions yet. This test crashes. When it stops crashing, consider
+ // adding assertion(s).
+ }
+
Future<void> test_field_final_does_not_override_setter() async {
await analyze('''
abstract class A {
diff --git a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
index e314cf2..77ca56e 100644
--- a/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/navigation_tree_renderer_test.dart
@@ -2,14 +2,12 @@
// 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/memory_file_system.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:path/path.dart' as path;
import 'nnbd_migration_test_base.dart';
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 4bc0b9d..13635f2 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -37,7 +37,8 @@
loggerFactory: (isVerbose) => test.logger = _TestLogger(isVerbose),
defaultSdkPathOverride:
test.resourceProvider.convertPath(mock_sdk.sdkRoot),
- resourceProvider: test.resourceProvider);
+ resourceProvider: test.resourceProvider,
+ processManager: test.processManager);
@override
Future<void> blockUntilSignalInterrupt() async {
@@ -61,6 +62,8 @@
abstract class _MigrationCliTestBase {
void set logger(_TestLogger logger);
+ _MockProcessManager get processManager;
+
MemoryResourceProvider get resourceProvider;
}
@@ -139,6 +142,32 @@
}
}
+ void assertPubOutdatedFailure(
+ {int pubOutdatedExitCode = 0,
+ String pubOutdatedStdout = '',
+ String pubOutdatedStderr = ''}) {
+ processManager._mockResult = ProcessResult(123 /* pid */,
+ pubOutdatedExitCode, pubOutdatedStdout, pubOutdatedStderr);
+ logger = _TestLogger(true);
+ var success =
+ DependencyChecker(resourceProvider.pathContext, logger, processManager)
+ .check();
+ expect(success, isFalse);
+ }
+
+ void assertPubOutdatedSuccess(
+ {int pubOutdatedExitCode = 0,
+ String pubOutdatedStdout = '',
+ String pubOutdatedStderr = ''}) {
+ processManager._mockResult = ProcessResult(123 /* pid */,
+ pubOutdatedExitCode, pubOutdatedStdout, pubOutdatedStderr);
+ logger = _TestLogger(true);
+ var success =
+ DependencyChecker(resourceProvider.pathContext, logger, processManager)
+ .check();
+ expect(success, isTrue);
+ }
+
String createProjectDir(Map<String, String> contents,
{String posixPath = '/test_project'}) {
for (var entry in contents.entries) {
@@ -266,6 +295,20 @@
expect(assertParseArgsSuccess(['--ignore-errors']).ignoreErrors, isTrue);
}
+ test_flag_skip_pub_outdated_default() {
+ expect(assertParseArgsSuccess([]).skipPubOutdated, isFalse);
+ }
+
+ test_flag_skip_pub_outdated_disable() async {
+ // "--no-skip-pub-outdated" is not an option.
+ await assertParseArgsFailure(['--no-skip-pub-outdated']);
+ }
+
+ test_flag_skip_pub_outdated_enable() {
+ expect(assertParseArgsSuccess(['--skip-pub-outdated']).skipPubOutdated,
+ isTrue);
+ }
+
test_flag_web_preview_default() {
expect(assertParseArgsSuccess([]).webPreview, isTrue);
}
@@ -406,6 +449,39 @@
});
}
+ test_lifecycle_preview_navigation_tree() async {
+ var projectContents = simpleProject(sourceText: 'int x;');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, [projectDir], (url) async {
+ expect(
+ logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await assertPreviewServerResponsive(url);
+ var uri = Uri.parse(url);
+ var authToken = uri.queryParameters['authToken'];
+ var treeResponse = await http.get(
+ uri.replace(
+ path: '/_preview/navigationTree.json',
+ queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ var navRoots = jsonDecode(treeResponse.body);
+ for (final root in navRoots) {
+ var navTree = NavigationTreeNode.fromJson(root);
+ for (final file in navTree.subtree) {
+ if (file.href != null) {
+ print(file.href);
+ final contentsResponse = await http.get(
+ uri
+ .resolve(file.href)
+ .replace(queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ assertHttpSuccess(contentsResponse);
+ }
+ }
+ }
+ });
+ }
+
test_lifecycle_preview_region_link() async {
var projectContents = simpleProject(sourceText: 'int x;');
var projectDir = await createProjectDir(projectContents);
@@ -621,7 +697,6 @@
headers: {'Content-Type': 'application/json; charset=UTF-8'});
var regionJson = EditDetails.fromJson(jsonDecode(regionResponse.body));
final traceEntry = regionJson.traces[0].entries[0];
- final displayPath = traceEntry.link.path;
final uriPath = traceEntry.link.href;
// uriPath should be a working URI
final contentsResponse = await http.get(
@@ -633,36 +708,49 @@
});
}
- test_lifecycle_preview_navigation_tree() async {
- var projectContents = simpleProject(sourceText: 'int x;');
+ test_lifecycle_skip_pub_outdated_disable() async {
+ var projectContents = simpleProject(sourceText: '''
+int f() => null;
+''');
var projectDir = await createProjectDir(projectContents);
+ processManager._mockResult = ProcessResult(
+ 123 /* pid */,
+ 0 /* exitCode */,
+ '''
+{ "packages":
+ [
+ { "package": "abc", "current": { "version": "1.0.0", "nullSafety": false } }
+ ]
+}
+''' /* stdout */,
+ '' /* stderr */);
var cli = _createCli();
- await runWithPreviewServer(cli, [projectDir], (url) async {
- expect(
- logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await cli.run(_parseArgs([projectDir]));
+ var output = logger.stderrBuffer.toString();
+ expect(output, contains('Warning: dependencies are outdated.'));
+ expect(cli.exitCode, 1);
+ }
+
+ test_lifecycle_skip_pub_outdated_enable() async {
+ var projectContents = simpleProject(sourceText: '''
+int f() => null;
+''');
+ var projectDir = await createProjectDir(projectContents);
+ processManager._mockResult = ProcessResult(
+ 123 /* pid */,
+ 0 /* exitCode */,
+ '''
+{ "packages":
+ [
+ { "package": "abc", "current": { "version": "1.0.0", "nullSafety": false } }
+ ]
+}
+''' /* stdout */,
+ '' /* stderr */);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, ['--skip-pub-outdated', projectDir],
+ (url) async {
await assertPreviewServerResponsive(url);
- var uri = Uri.parse(url);
- var authToken = uri.queryParameters['authToken'];
- var treeResponse = await http.get(
- uri.replace(
- path: '/_preview/navigationTree.json',
- queryParameters: {'authToken': authToken}),
- headers: {'Content-Type': 'application/json; charset=UTF-8'});
- var navRoots = jsonDecode(treeResponse.body);
- for (final root in navRoots) {
- var navTree = NavigationTreeNode.fromJson(root);
- for (final file in navTree.subtree) {
- if (file.href != null) {
- print(file.href);
- final contentsResponse = await http.get(
- uri
- .resolve(file.href)
- .replace(queryParameters: {'authToken': authToken}),
- headers: {'Content-Type': 'application/json; charset=UTF-8'});
- assertHttpSuccess(contentsResponse);
- }
- }
- }
});
}
@@ -835,6 +923,134 @@
'Could not find an option named "this-option-does-not-exist"'));
}
+ test_pub_outdated_has_malformed_json() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '{ "packages": }');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_no_packages() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '{}');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_no_pre_null_safety_packages() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc",
+ "current": { "version": "1.0.0", "nullSafety": true }
+ },
+ {
+ "package": "def",
+ "current": { "version": "2.0.0", "nullSafety": true }
+ }
+ ]
+}
+''');
+ }
+
+ test_pub_outdated_has_one_pre_null_safety_package() {
+ assertPubOutdatedFailure(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc",
+ "current": { "version": "1.0.0", "nullSafety": false }
+ },
+ {
+ "package": "def",
+ "current": { "version": "2.0.0", "nullSafety": true }
+ }
+ ]
+}
+''');
+ var stderrText = logger.stderrBuffer.toString();
+ expect(stderrText, contains('Warning:'));
+ expect(stderrText, contains('abc'));
+ expect(stderrText, contains('1.0.0'));
+ }
+
+ test_pub_outdated_has_package_with_missing_current() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc"
+ }
+ ]
+}
+''');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_package_with_missing_name() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "current": {
+ "version": "1.0.0",
+ "nullSafety": false
+ }
+ }
+ ]
+}
+''');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_package_with_missing_nullSafety() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc",
+ "current": {
+ "version": "1.0.0"
+ }
+ }
+ ]
+}
+''');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_package_with_missing_version() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc",
+ "current": {
+ "nullSafety": false
+ }
+ }
+ ]
+}
+''');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
+ test_pub_outdated_has_package_with_null_current() {
+ assertPubOutdatedSuccess(pubOutdatedStdout: '''
+{
+ "packages": [
+ {
+ "package": "abc",
+ "current": null
+ }
+ ]
+}
+''');
+ expect(logger.stderrBuffer.toString(), isEmpty);
+ }
+
+ test_pub_outdated_has_stderr() {
+ assertPubOutdatedSuccess(pubOutdatedStderr: 'anything');
+ expect(logger.stderrBuffer.toString(), startsWith('Warning:'));
+ }
+
test_uses_physical_resource_provider_by_default() {
var cli = MigrationCli(binaryName: 'nnbd_migration');
expect(cli.resourceProvider, same(PhysicalResourceProvider.INSTANCE));
@@ -874,12 +1090,16 @@
@override
final resourceProvider;
+ @override
+ final processManager;
+
_MigrationCliTestPosix()
: resourceProvider = MemoryResourceProvider(
context: path.style == path.Style.posix
? null
: path.Context(
- style: path.Style.posix, current: '/working_dir'));
+ style: path.Style.posix, current: '/working_dir')),
+ processManager = _MockProcessManager();
}
@reflectiveTest
@@ -888,12 +1108,31 @@
@override
final resourceProvider;
+ @override
+ final processManager;
+
_MigrationCliTestWindows()
: resourceProvider = MemoryResourceProvider(
context: path.style == path.Style.windows
? null
: path.Context(
- style: path.Style.windows, current: 'C:\\working_dir'));
+ style: path.Style.windows, current: 'C:\\working_dir')),
+ processManager = _MockProcessManager();
+}
+
+class _MockProcessManager implements ProcessManager {
+ ProcessResult _mockResult;
+
+ dynamic noSuchMethod(Invocation invocation) {}
+
+ ProcessResult runSync(String executable, List<String> arguments) =>
+ _mockResult ??
+ ProcessResult(
+ 123 /* pid */,
+ 0 /* exitCode */,
+ '' /* stdout */,
+ '' /* stderr */,
+ );
}
/// TODO(paulberry): move into cli_util
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 6eec3f2..eb54807 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -536,11 +536,11 @@
@override
int compareTo(AnalyzerError other) {
- if (severity != other.severity) return severity.compareTo(other.severity);
if (file != other.file) return file.compareTo(other.file);
if (line != other.line) return line.compareTo(other.line);
if (column != other.column) return column.compareTo(other.column);
if (length != other.length) return length.compareTo(other.length);
+ if (severity != other.severity) return severity.compareTo(other.severity);
if (errorCode != other.errorCode) {
return errorCode.compareTo(other.errorCode);
}
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index fe588a6..6be64fb 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -541,10 +541,7 @@
// Link to the summaries for the available packages, so that they don't
// get recompiled into the test's own module.
- var packages = _configuration.nnbdMode == NnbdMode.legacy
- ? testPackages
- : testPackagesNnbd;
- for (var package in packages) {
+ for (var package in testPackages) {
args.add("-s");
// Since the summaries for the packages are not near the tests, we give
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index c75180c..540dfd2 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -305,15 +305,16 @@
hasRuntimeError: testExpectation == Expectation.runtimeError,
hasStaticWarning: false,
hasCrash: testExpectation == Expectation.crash);
-
var filename = configuration.architecture == Architecture.x64
? '$buildDir/gen/kernel-service.dart.snapshot'
: '$buildDir/gen/kernel_service.dill';
var dfePath = Path(filename).absolute.toNativePath();
var args = [
- if (expectations.contains(Expectation.crash)) '--suppress-core-dump',
// '--dfe' has to be the first argument for run_vm_test to pick it up.
'--dfe=$dfePath',
+ if (expectations.contains(Expectation.crash)) '--suppress-core-dump',
+ if (configuration.experiments.isNotEmpty)
+ '--enable-experiment=${configuration.experiments.join(",")}',
...configuration.standardOptions,
...configuration.vmOptions,
test.name
diff --git a/pkg/test_runner/lib/src/utils.dart b/pkg/test_runner/lib/src/utils.dart
index 7daa0eb..ba61a15 100644
--- a/pkg/test_runner/lib/src/utils.dart
+++ b/pkg/test_runner/lib/src/utils.dart
@@ -21,22 +21,6 @@
/// The names of the packages that are available for use in tests.
const testPackages = [
"async_helper",
- "collection",
- "expect",
- "js",
- "matcher",
- "meta",
- "path",
- "stack_trace"
-];
-
-// TODO(nshahan): Grow this list until it matches the list above. We are
-// temporarily using a reduced set of packages in tests until they are compliant
-// or we can simply opt them out of the null safety feature without build
-// errors. This list should be consistent with the build target
-// utils/dartdevc:dartdevc_test_kernel_pkg
-const testPackagesNnbd = [
- "async_helper",
"expect",
"js",
"meta",
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index fcdd01d..a8017d7 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -223,8 +223,9 @@
}
var errors = <StaticError>[];
- AnalysisCommandOutput.parseErrors(result.stderr as String, errors);
- return errors;
+ var warnings = <StaticError>[];
+ AnalysisCommandOutput.parseErrors(result.stderr as String, errors, warnings);
+ return [...errors, ...warnings];
}
/// Invoke CFE on [path] and gather all static errors it reports.
diff --git a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
index 83bcdd1..2704c99 100644
--- a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
+++ b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
@@ -178,15 +178,18 @@
}
@override
- visitLet(Let node) {
+ visitBlockExpression(BlockExpression node) {
// The BuilderInfo field `_i` is set up with a row of cascaded calls.
// ```
// static final BuilderInfo _i = BuilderInfo('MessageName')
// ..a(1, 'foo', PbFieldType.OM)
// ..a(2, 'bar', PbFieldType.OM)
// ```
- // Each cascaded call will be represented in kernel as a let, where the
- // initializer will be a call to a method of `builderInfo`. For example:
+ // Each cascaded call will be represented in kernel as an entry in a
+ // BlockExpression (but starts out in a Let), where each statement in block
+ // is an ExpressionStatement, and where each statement will be a call to a
+ // method of `builderInfo`.
+ // For example:
// ```
// {protobuf::BuilderInfo::a}<dart.core::int*>(1, "foo", #C10)
// ```
@@ -196,7 +199,21 @@
// First argument is the tag-number of the added field.
// Second argument is the field-name.
// Further arguments are specific to the method.
- final initializer = node.variable.initializer;
+ for (Statement statement in node.body.statements) {
+ if (statement is ExpressionStatement) {
+ _changeCascadeEntry(statement.expression);
+ }
+ }
+ node.body.accept(this);
+ }
+
+ @override
+ visitLet(Let node) {
+ // See comment in visitBlockExpression.
+ node.body.accept(this);
+ }
+
+ void _changeCascadeEntry(Expression initializer) {
if (initializer is MethodInvocation &&
initializer.interfaceTarget?.enclosingClass == builderInfoClass &&
fieldAddingMethods.contains(initializer.name.name)) {
@@ -233,7 +250,6 @@
);
}
}
- node.body.accept(this);
}
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
index 7857d67..223a0ed 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_is_prime.dart.expect
@@ -30,7 +30,9 @@
}
}
static method main(core::List<core::String*>* args) → dynamic {
- core::Stopwatch* timer = let final core::Stopwatch #t1 = new core::Stopwatch::•() in let final void #t2 = [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}() in #t1;
+ core::Stopwatch* timer = let final core::Stopwatch #t1 = new core::Stopwatch::•() in block {
+ [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t1.{core::Stopwatch::start}();
+ } =>#t1;
for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::run();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index d40f897..d941915 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -27,7 +27,9 @@
[@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector* v = new self::_Vector::•(10);
[@vm.inferred-type.metadata=dart.core::_Double?]static field core::double* x = 0.0;
static method main(core::List<core::String*>* args) → dynamic {
- core::Stopwatch* timer = let final core::Stopwatch #t3 = new core::Stopwatch::•() in let final void #t4 = [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t3.{core::Stopwatch::start}() in #t3;
+ core::Stopwatch* timer = let final core::Stopwatch #t3 = new core::Stopwatch::•() in block {
+ [@vm.direct-call.metadata=Stopwatch.start] [@vm.inferred-type.metadata=!? (skip check)] #t3.{core::Stopwatch::start}();
+ } =>#t3;
for (core::int* i = 0; [@vm.direct-call.metadata=_IntegerImplementation.<] [@vm.inferred-type.metadata=dart.core::bool (skip check)] i.{core::num::<}(100000000); i = [@vm.direct-call.metadata=_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] i.{core::num::+}(1)) {
self::x = [@vm.direct-call.metadata=_Double.+??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=dart.core::_Double?] self::x.{core::double::+}([@vm.direct-call.metadata=_Vector.*??] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] [@vm.inferred-type.metadata=#lib::_Vector?] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector?] self::v));
}
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 70f5ded..a64881c 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog
+## 4.1.0
+- Expose more `@required` parameters on the named constructors of VM service objects.
+
## 4.0.4
- Update to version `3.34.0` of the spec.
- Fixed issue where `TimelineEvents` was not a valid service event kind.
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 01f4ea3..c3bc86a 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -2756,8 +2756,9 @@
@required this.breakpointNumber,
@required this.resolved,
@required this.location,
+ @required String id,
this.isSyntheticAsyncContinuation,
- });
+ }) : super(id: id);
Breakpoint._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
breakpointNumber = json['breakpointNumber'];
@@ -2800,7 +2801,8 @@
ClassRef({
@required this.name,
- });
+ @required String id,
+ }) : super(id: id);
ClassRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -2888,12 +2890,13 @@
@required this.fields,
@required this.functions,
@required this.subclasses,
+ @required String id,
this.error,
this.location,
this.superClass,
this.superType,
this.mixin,
- });
+ }) : super(id: id);
Class._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -3071,7 +3074,8 @@
CodeRef({
@required this.name,
@required this.kind,
- });
+ @required String id,
+ }) : super(id: id);
CodeRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -3111,7 +3115,8 @@
Code({
@required this.name,
@required this.kind,
- });
+ @required String id,
+ }) : super(id: id);
Code._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -3146,7 +3151,8 @@
ContextRef({
@required this.length,
- });
+ @required String id,
+ }) : super(id: id);
ContextRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
@@ -3189,8 +3195,9 @@
Context({
@required this.length,
@required this.variables,
+ @required String id,
this.parent,
- });
+ }) : super(id: id);
Context._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
@@ -3416,7 +3423,8 @@
ErrorRef({
@required this.kind,
@required this.message,
- });
+ @required String id,
+ }) : super(id: id);
ErrorRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
@@ -3467,9 +3475,10 @@
Error({
@required this.kind,
@required this.message,
+ @required String id,
this.exception,
this.stacktrace,
- });
+ }) : super(id: id);
Error._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
@@ -3827,7 +3836,8 @@
@required this.isConst,
@required this.isFinal,
@required this.isStatic,
- });
+ @required String id,
+ }) : super(id: id);
FieldRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -3902,9 +3912,10 @@
@required this.isConst,
@required this.isFinal,
@required this.isStatic,
+ @required String id,
this.staticValue,
this.location,
- });
+ }) : super(id: id);
Field._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -4107,7 +4118,8 @@
@required this.owner,
@required this.isStatic,
@required this.isConst,
- });
+ @required String id,
+ }) : super(id: id);
FuncRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -4171,9 +4183,10 @@
@required this.owner,
@required this.isStatic,
@required this.isConst,
+ @required String id,
this.location,
this.code,
- });
+ }) : super(id: id);
Func._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -4313,6 +4326,7 @@
InstanceRef({
@required this.kind,
@required this.classRef,
+ @required String id,
this.valueAsString,
this.valueAsStringIsTruncated,
this.length,
@@ -4322,7 +4336,7 @@
this.pattern,
this.closureFunction,
this.closureContext,
- });
+ }) : super(id: id);
InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
@@ -4627,6 +4641,7 @@
Instance({
@required this.kind,
@required this.classRef,
+ @required String id,
this.valueAsString,
this.valueAsStringIsTruncated,
this.length,
@@ -4651,7 +4666,7 @@
this.parameterIndex,
this.targetType,
this.bound,
- });
+ }) : super(id: id);
Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
@@ -5144,7 +5159,8 @@
LibraryRef({
@required this.name,
@required this.uri,
- });
+ @required String id,
+ }) : super(id: id);
LibraryRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -5210,7 +5226,8 @@
@required this.variables,
@required this.functions,
@required this.classes,
- });
+ @required String id,
+ }) : super(id: id);
Library._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
@@ -6068,7 +6085,8 @@
ScriptRef({
@required this.uri,
- });
+ @required String id,
+ }) : super(id: id);
ScriptRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
uri = json['uri'];
@@ -6153,11 +6171,12 @@
Script({
@required this.uri,
@required this.library,
+ @required String id,
this.lineOffset,
this.columnOffset,
this.source,
this.tokenPosTable,
- });
+ }) : super(id: id);
Script._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
uri = json['uri'];
@@ -6688,7 +6707,8 @@
TypeArgumentsRef({
@required this.name,
- });
+ @required String id,
+ }) : super(id: id);
TypeArgumentsRef._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
@@ -6731,7 +6751,8 @@
TypeArguments({
@required this.name,
@required this.types,
- });
+ @required String id,
+ }) : super(id: id);
TypeArguments._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index c066883..568f09c 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
-version: 4.0.4
+version: 4.1.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 146ec47..ba1b0fe 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -1399,7 +1399,11 @@
gen.writeln();
if (docs != null) gen.writeDocs(docs);
gen.write('class ${name} ');
- if (superName != null) gen.write('extends ${superName} ');
+ Type superType;
+ if (superName != null) {
+ superType = parent.getType(superName);
+ gen.write('extends ${superName} ');
+ }
if (parent.getType('${name}Ref') != null) {
gen.write('implements ${name}Ref ');
}
@@ -1422,6 +1426,8 @@
// ctors
+ bool hasRequiredParentFields = superType != null &&
+ (superType.name == 'ObjRef' || superType.name == 'Obj');
// Default
gen.write('${name}(');
if (fields.isNotEmpty) {
@@ -1429,12 +1435,25 @@
fields
.where((field) => !field.optional)
.forEach((field) => field.generateNamedParameter(gen));
+ if (hasRequiredParentFields) {
+ superType.fields.where((field) => !field.optional).forEach(
+ (field) => field.generateNamedParameter(gen, fromParent: true));
+ }
fields
.where((field) => field.optional)
.forEach((field) => field.generateNamedParameter(gen));
gen.write('}');
}
- gen.writeln(');');
+ gen.write(')');
+ if (hasRequiredParentFields) {
+ gen.write(' : super(');
+ superType.fields.where((field) => !field.optional).forEach((field) {
+ String name = field.generatableName;
+ gen.write('$name: $name');
+ });
+ gen.write(')');
+ }
+ gen.writeln(';');
// Build from JSON.
gen.writeln();
@@ -1833,11 +1852,17 @@
if (parent.fields.any((field) => field.hasDocs)) gen.writeln();
}
- void generateNamedParameter(DartGenerator gen) {
+ void generateNamedParameter(DartGenerator gen, {bool fromParent = false}) {
if (!optional) {
gen.write('@required ');
}
- gen.writeStatement('this.${generatableName},');
+ if (fromParent) {
+ String typeName =
+ api.isEnumName(type.name) ? '/*${type.name}*/ String' : type.name;
+ gen.writeStatement('$typeName ${generatableName},');
+ } else {
+ gen.writeStatement('this.${generatableName},');
+ }
}
}
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 71d0437..f1eeeb2 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -652,8 +652,8 @@
Dart_Handle DartUtils::GetDartType(const char* library_url,
const char* class_name) {
- return Dart_GetType(Dart_LookupLibrary(NewString(library_url)),
- NewString(class_name), 0, NULL);
+ return Dart_GetNonNullableType(Dart_LookupLibrary(NewString(library_url)),
+ NewString(class_name), 0, NULL);
}
Dart_Handle DartUtils::NewDartOSError() {
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index 726ecd1..ec96863 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -10,8 +10,8 @@
#include <errno.h> // NOLINT
#include <sys/stat.h> // NOLINT
-#include "bin/dartutils.h"
#include "bin/crypto.h"
+#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/namespace.h"
#include "bin/utils.h"
@@ -450,8 +450,8 @@
// a uuid.
uint32_t suffix_bytes = 0;
const int kSuffixSize = sizeof(suffix_bytes);
- if (!Crypto::GetRandomBytes(
- kSuffixSize, reinterpret_cast<uint8_t*>(&suffix_bytes))) {
+ if (!Crypto::GetRandomBytes(kSuffixSize,
+ reinterpret_cast<uint8_t*>(&suffix_bytes))) {
// Getting random bytes failed, maybe the UUID will work?
return CreateTempFromUUID(prefix);
}
diff --git a/runtime/bin/elf_loader.cc b/runtime/bin/elf_loader.cc
index 8910736a..b3981bd 100644
--- a/runtime/bin/elf_loader.cc
+++ b/runtime/bin/elf_loader.cc
@@ -6,6 +6,7 @@
#include <bin/file.h>
#include <platform/elf.h>
#include <platform/globals.h>
+#include <vm/bss_relocs.h>
#include <vm/cpu.h>
#include <vm/virtual_memory.h>
@@ -183,6 +184,9 @@
/// corresponding symbol was not found, or if the dynamic symbol table could
/// not be decoded.
///
+ /// Has the side effect of initializing the relocated addresses for the text
+ /// sections corresponding to non-null output parameters in the BSS segment.
+ ///
/// On failure, the error may be retrieved by 'error()'.
bool ResolveSymbols(const uint8_t** vm_data,
const uint8_t** vm_instrs,
@@ -235,6 +239,8 @@
const char* dynamic_string_table_ = nullptr;
const dart::elf::Symbol* dynamic_symbol_table_ = nullptr;
uword dynamic_symbol_count_ = 0;
+ uword* vm_bss_ = nullptr;
+ uword* isolate_bss_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(LoadedElf);
};
@@ -462,11 +468,21 @@
dynamic_symbol_table_ = reinterpret_cast<const dart::elf::Symbol*>(
base_->start() + header.memory_offset);
dynamic_symbol_count_ = header.file_size / sizeof(dart::elf::Symbol);
+ } else if (strcmp(name, ".bss") == 0) {
+ auto const bss_size =
+ (BSS::kVmEntryCount + BSS::kIsolateEntryCount) * kWordSize;
+ CHECK_ERROR(header.memory_offset != 0, ".bss must be loaded.");
+ CHECK_ERROR(header.file_size >= bss_size,
+ ".bss does not have enough space.");
+ vm_bss_ = reinterpret_cast<uword*>(base_->start() + header.memory_offset);
+ isolate_bss_ = vm_bss_ + BSS::kVmEntryCount;
+ // We set applicable BSS entries in ResolveSymbols().
}
}
CHECK_ERROR(dynamic_string_table_ != nullptr, "Couldn't find .dynstr.");
CHECK_ERROR(dynamic_symbol_table_ != nullptr, "Couldn't find .dynsym.");
+ CHECK_ERROR(vm_bss_ != nullptr, "Couldn't find .bss.");
return true;
}
@@ -488,10 +504,22 @@
output = vm_data;
} else if (strcmp(name, kVmSnapshotInstructionsAsmSymbol) == 0) {
output = vm_instrs;
+ if (output != nullptr) {
+ // Store the value of the symbol in the VM BSS, as it contains the
+ // address of the VM instructions section relative to the DSO base.
+ BSS::InitializeBSSEntry(BSS::Relocation::InstructionsRelocatedAddress,
+ sym.value, vm_bss_);
+ }
} else if (strcmp(name, kIsolateSnapshotDataAsmSymbol) == 0) {
output = isolate_data;
} else if (strcmp(name, kIsolateSnapshotInstructionsAsmSymbol) == 0) {
output = isolate_instrs;
+ if (output != nullptr) {
+ // Store the value of the symbol in the isolate BSS, as it contains the
+ // address of the isolate instructions section relative to the DSO base.
+ BSS::InitializeBSSEntry(BSS::Relocation::InstructionsRelocatedAddress,
+ sym.value, isolate_bss_);
+ }
}
if (output != nullptr) {
diff --git a/runtime/bin/exe_utils.cc b/runtime/bin/exe_utils.cc
index d9333dc..9950ae6fa 100644
--- a/runtime/bin/exe_utils.cc
+++ b/runtime/bin/exe_utils.cc
@@ -67,7 +67,7 @@
Utils::CStringUniquePtr EXEUtils::GetDirectoryPrefixFromExeName() {
const char* name = nullptr;
- const int kTargetSize = 4096;
+ const int kTargetSize = PATH_MAX;
char target[kTargetSize];
intptr_t target_size =
Platform::ResolveExecutablePathInto(target, kTargetSize);
@@ -81,6 +81,7 @@
ASSERT(target_size < kTargetSize);
}
Namespace* namespc = Namespace::Create(Namespace::Default());
+ char* result;
if (File::GetType(namespc, name, false) == File::kIsLink) {
char dir_path[kTargetSize];
// cwd is currently wherever we launched from, so set the cwd to the
@@ -102,11 +103,20 @@
} while (File::GetType(namespc, name, false) == File::kIsLink);
target_size = strlen(name);
+ char absolute_path[kTargetSize];
+
+ // Get the absolute path after we've resolved all the symlinks and before
+ // we reset the cwd, otherwise path resolution will fail.
+ File::GetCanonicalPath(namespc, name, absolute_path, kTargetSize);
+
// Reset cwd to the original value.
Directory::SetCurrent(namespc, initial_dir_path.get());
+
+ result = GetDirectoryFromPath(absolute_path, nullptr);
+ } else {
+ result = GetDirectoryFromPath(target, nullptr);
}
namespc->Release();
- char* result = GetDirectoryFromPath(name, nullptr);
return Utils::CreateCStringUniquePtr(result == nullptr ? strdup("") : result);
}
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 642ba9e..d900b10 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -261,9 +261,12 @@
// The result will be populated into dest.
static const char* LinkTarget(Namespace* namespc,
const char* pathname,
- char* dest = NULL,
+ char* dest = nullptr,
int dest_size = 0);
- static const char* GetCanonicalPath(Namespace* namespc, const char* path);
+ static const char* GetCanonicalPath(Namespace* namespc,
+ const char* path,
+ char* dest = nullptr,
+ int dest_size = 0);
// Link LinkTarget, but pathname must be absolute.
static const char* ReadLink(const char* pathname);
static intptr_t ReadLinkInto(const char* pathname,
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 15352c0..2a3ffd4 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -652,7 +652,10 @@
return target_name;
}
-const char* File::GetCanonicalPath(Namespace* namespc, const char* name) {
+const char* File::GetCanonicalPath(Namespace* namespc,
+ const char* name,
+ char* dest,
+ int dest_size) {
if (name == NULL) {
return NULL;
}
@@ -663,13 +666,17 @@
return name;
}
char* abs_path;
- char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
- ASSERT(resolved_path != NULL);
+ if (dest == NULL) {
+ dest = DartUtils::ScopedCString(PATH_MAX + 1);
+ } else {
+ ASSERT(dest_size >= PATH_MAX);
+ }
+ ASSERT(dest != NULL);
do {
- abs_path = realpath(name, resolved_path);
+ abs_path = realpath(name, dest);
} while ((abs_path == NULL) && (errno == EINTR));
ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
- ASSERT(abs_path == NULL || (abs_path == resolved_path));
+ ASSERT(abs_path == NULL || (abs_path == dest));
return abs_path;
}
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index 39d667b..89426c0 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -598,7 +598,10 @@
return ((pathname != NULL) && (pathname[0] == '/'));
}
-const char* File::GetCanonicalPath(Namespace* namespc, const char* name) {
+const char* File::GetCanonicalPath(Namespace* namespc,
+ const char* name,
+ char* dest,
+ int dest_size) {
if (name == NULL) {
return NULL;
}
@@ -609,13 +612,17 @@
return name;
}
char* abs_path;
- char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
- ASSERT(resolved_path != NULL);
+ if (dest == NULL) {
+ dest = DartUtils::ScopedCString(PATH_MAX + 1);
+ } else {
+ ASSERT(dest_size >= PATH_MAX);
+ }
+ ASSERT(dest != NULL);
do {
- abs_path = realpath(name, resolved_path);
+ abs_path = realpath(name, dest);
} while ((abs_path == NULL) && (errno == EINTR));
ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
- ASSERT(abs_path == NULL || (abs_path == resolved_path));
+ ASSERT(abs_path == NULL || (abs_path == dest));
return abs_path;
}
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index dab296d..92ee4fa 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -649,7 +649,10 @@
return target_name;
}
-const char* File::GetCanonicalPath(Namespace* namespc, const char* name) {
+const char* File::GetCanonicalPath(Namespace* namespc,
+ const char* name,
+ char* dest,
+ int dest_size) {
if (name == NULL) {
return NULL;
}
@@ -660,13 +663,17 @@
return name;
}
char* abs_path;
- char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
- ASSERT(resolved_path != NULL);
+ if (dest == NULL) {
+ dest = DartUtils::ScopedCString(PATH_MAX + 1);
+ } else {
+ ASSERT(dest_size >= PATH_MAX);
+ }
+ ASSERT(dest != NULL);
do {
- abs_path = realpath(name, resolved_path);
+ abs_path = realpath(name, dest);
} while ((abs_path == NULL) && (errno == EINTR));
ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
- ASSERT(abs_path == NULL || (abs_path == resolved_path));
+ ASSERT(abs_path == NULL || (abs_path == dest));
return abs_path;
}
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index bc6ef93..e87cced 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -573,19 +573,25 @@
return (pathname != NULL && pathname[0] == '/');
}
-const char* File::GetCanonicalPath(Namespace* namespc, const char* pathname) {
+const char* File::GetCanonicalPath(Namespace* namespc,
+ const char* pathname,
+ char* dest,
+ int dest_size) {
char* abs_path = NULL;
if (pathname != NULL) {
// On some older MacOs versions the default behaviour of realpath allocating
- // space for the resolved_path when a NULL is passed in does not seem to
- // work, so we explicitly allocate space.
- char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
- ASSERT(resolved_path != NULL);
+ // space for the dest when a NULL is passed in does not seem to work, so we
+ // explicitly allocate space.
+ if (dest == NULL) {
+ dest = DartUtils::ScopedCString(PATH_MAX + 1);
+ } else {
+ ASSERT(dest_size >= PATH_MAX);
+ }
do {
- abs_path = realpath(pathname, resolved_path);
+ abs_path = realpath(pathname, dest);
} while ((abs_path == NULL) && (errno == EINTR));
ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path));
- ASSERT((abs_path == NULL) || (abs_path == resolved_path));
+ ASSERT((abs_path == NULL) || (abs_path == dest));
}
return abs_path;
}
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 2dc6b95..ff32a17 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -678,7 +678,10 @@
((pathname[2] == '\\') || (pathname[2] == '/')));
}
-const char* File::GetCanonicalPath(Namespace* namespc, const char* pathname) {
+const char* File::GetCanonicalPath(Namespace* namespc,
+ const char* pathname,
+ char* dest,
+ int dest_size) {
Utf8ToWideScope system_name(pathname);
HANDLE file_handle =
CreateFileW(system_name.wide(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
@@ -695,23 +698,33 @@
SetLastError(error);
return NULL;
}
- wchar_t* path;
- path = reinterpret_cast<wchar_t*>(
- Dart_ScopeAllocate(required_size * sizeof(*path)));
- int result_size = GetFinalPathNameByHandle(file_handle, path, required_size,
- VOLUME_NAME_DOS);
+ auto path = std::unique_ptr<wchar_t[]>(new wchar_t[required_size]);
+ int result_size = GetFinalPathNameByHandle(file_handle, path.get(),
+ required_size, VOLUME_NAME_DOS);
ASSERT(result_size <= required_size - 1);
- // Remove leading \\?\ if possible, unless input used it.
- char* result;
- if ((result_size < MAX_PATH - 1 + 4) && (result_size > 4) &&
- (wcsncmp(path, L"\\\\?\\", 4) == 0) &&
- (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) {
- result = StringUtilsWin::WideToUtf8(path + 4);
- } else {
- result = StringUtilsWin::WideToUtf8(path);
- }
CloseHandle(file_handle);
- return result;
+
+ // Remove leading \\?\ if possible, unless input used it.
+ int offset = 0;
+ if ((result_size < MAX_PATH - 1 + 4) && (result_size > 4) &&
+ (wcsncmp(path.get(), L"\\\\?\\", 4) == 0) &&
+ (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) {
+ offset = 4;
+ }
+ int utf8_size = WideCharToMultiByte(CP_UTF8, 0, path.get() + offset, -1,
+ nullptr, 0, nullptr, nullptr);
+ if (dest == NULL) {
+ dest = DartUtils::ScopedCString(utf8_size);
+ dest_size = utf8_size;
+ }
+ if (dest_size != 0) {
+ ASSERT(utf8_size <= dest_size);
+ }
+ if (0 == WideCharToMultiByte(CP_UTF8, 0, path.get() + offset, -1, dest,
+ dest_size, NULL, NULL)) {
+ return NULL;
+ }
+ return dest;
}
const char* File::PathSeparator() {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 8742d98..3a49f5d 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -76,8 +76,12 @@
static Dart_Handle CreateRuntimeOptions(CommandLineOptions* options) {
int options_count = options->count();
+ Dart_Handle string_type = DartUtils::GetDartType("dart:core", "String");
+ if (Dart_IsError(string_type)) {
+ return string_type;
+ }
Dart_Handle dart_arguments =
- Dart_NewListOf(Dart_CoreType_String, options_count);
+ Dart_NewListOfTypeFilled(string_type, Dart_EmptyString(), options_count);
if (Dart_IsError(dart_arguments)) {
return dart_arguments;
}
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 20003a0..1b04cfc 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -72,7 +72,10 @@
void FUNCTION_NAME(Platform_ExecutableArguments)(Dart_NativeArguments args) {
int end = Platform::GetScriptIndex();
char** argv = Platform::GetArgv();
- Dart_Handle result = Dart_NewListOf(Dart_CoreType_String, end - 1);
+ Dart_Handle string_type = DartUtils::GetDartType("dart:core", "String");
+ ThrowIfError(string_type);
+ Dart_Handle result =
+ Dart_NewListOfTypeFilled(string_type, Dart_EmptyString(), end - 1);
for (intptr_t i = 1; i < end; i++) {
Dart_Handle str = DartUtils::NewString(argv[i]);
ThrowIfError(str);
diff --git a/runtime/docs/aot_binary_size_analysis.md b/runtime/docs/aot_binary_size_analysis.md
index 744f568..04a8e41 100644
--- a/runtime/docs/aot_binary_size_analysis.md
+++ b/runtime/docs/aot_binary_size_analysis.md
@@ -29,7 +29,7 @@
size analysis tool:
```
-% dart pkg/vm/bin/run_binary_size_analysis.dart hello_sizes.json hello_sizes
+% dart pkg/vm/bin/snapshot_analysis.dart treemap hello_sizes.json hello_sizes
Generated file:///.../sdk/hello_sizes/index.html
% chrome hello_sizes/index.html
```
@@ -41,7 +41,7 @@
comparison tool:
```
-% dart pkg/vm/bin/compare_sizes.dart app-sizes--before.json app-sizes--after.json
+% dart pkg/vm/bin/snapshot_analysis.dart compare app-sizes--before.json app-sizes--after.json
+---------+--------+--------------+
| Library | Method | Diff (Bytes) |
diff --git a/runtime/tools/ffi/sdk_lib_ffi_generator.dart b/runtime/tools/ffi/sdk_lib_ffi_generator.dart
index 500f64a..1b3b364 100644
--- a/runtime/tools/ffi/sdk_lib_ffi_generator.dart
+++ b/runtime/tools/ffi/sdk_lib_ffi_generator.dart
@@ -170,15 +170,13 @@
$alignment external $typedListType asTypedList(int length);
""";
- // TODO(38892): Stop generating documentation on setter.
buffer.write("""
/// Extension on [Pointer] specialized for the type argument [$nativeType].
extension ${nativeType}Pointer on Pointer<$nativeType> {
/// The $property at [address].
$platform$truncate$alignment external $dartType get value;
- /// The $property at [address].
-$platform$truncate$alignment external void set value($dartType value);
+ external void set value($dartType value);
/// The $property at `address + ${sizeTimes}index`.
$platform$truncate$alignment external $dartType operator [](int index);
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 11527a7..c7512c4 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -268,12 +268,12 @@
const char* kScriptChars =
"import 'dart:nativewrappers';\n"
"class Class extends NativeFieldWrapperClass1 {\n"
- " int init() native 'init';\n"
+ " void init() native 'init';\n"
" int method(int param1, int param2) native 'method';\n"
"}\n"
"\n"
"void benchmark(int count) {\n"
- " Class c = new Class();\n"
+ " Class c = Class();\n"
" c.init();\n"
" for (int i = 0; i < count; i++) {\n"
" c.method(i,7);\n"
@@ -359,6 +359,10 @@
// Measure compile of all kernel Service(CFE) functions.
//
BENCHMARK(KernelServiceCompileAll) {
+ if (FLAG_null_safety == kNullSafetyOptionStrong) {
+ // TODO(bkonyi): remove this check when we build the CFE in strong mode.
+ return;
+ }
bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
diff --git a/runtime/vm/bss_relocs.cc b/runtime/vm/bss_relocs.cc
index 7df4242..2ca72c5 100644
--- a/runtime/vm/bss_relocs.cc
+++ b/runtime/vm/bss_relocs.cc
@@ -3,28 +3,41 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/bss_relocs.h"
+#include "vm/native_symbol.h"
#include "vm/runtime_entry.h"
#include "vm/thread.h"
namespace dart {
-static void InitializeBSSEntry(BSS::Relocation relocation,
- uword function_address,
- uword* bss_start) {
+void BSS::InitializeBSSEntry(BSS::Relocation relocation,
+ uword new_value,
+ uword* bss_start) {
std::atomic<uword>* slot = reinterpret_cast<std::atomic<uword>*>(
&bss_start[BSS::RelocationIndex(relocation)]);
uword old_value = slot->load(std::memory_order_relaxed);
- uword new_value = function_address;
if (!slot->compare_exchange_strong(old_value, new_value,
std::memory_order_relaxed)) {
RELEASE_ASSERT(old_value == new_value);
}
}
-void BSS::Initialize(Thread* current, uword* bss_start) {
- InitializeBSSEntry(BSS::Relocation::DRT_GetThreadForNativeCallback,
- reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback),
- bss_start);
+void BSS::Initialize(Thread* current, uword* bss_start, bool vm) {
+ auto const instructions = reinterpret_cast<uword>(
+ current->isolate_group()->source()->snapshot_instructions);
+ uword dso_base;
+ // For non-natively loaded snapshots, this is instead initialized in
+ // LoadedElf::ResolveSymbols().
+ if (NativeSymbolResolver::LookupSharedObject(instructions, &dso_base)) {
+ InitializeBSSEntry(Relocation::InstructionsRelocatedAddress,
+ instructions - dso_base, bss_start);
+ }
+
+ if (!vm) {
+ // Fill values at isolate-only indices.
+ InitializeBSSEntry(Relocation::DRT_GetThreadForNativeCallback,
+ reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback),
+ bss_start);
+ }
}
} // namespace dart
diff --git a/runtime/vm/bss_relocs.h b/runtime/vm/bss_relocs.h
index c557b46..d013c5d 100644
--- a/runtime/vm/bss_relocs.h
+++ b/runtime/vm/bss_relocs.h
@@ -12,16 +12,33 @@
class BSS : public AllStatic {
public:
+ // Entries found in both the VM and isolate BSS come first. Each has its own
+ // portion of the BSS segment, so just the indices are shared, not the values
+ // stored at the index.
enum class Relocation : intptr_t {
- DRT_GetThreadForNativeCallback = 0,
- NumRelocations = 1
+ InstructionsRelocatedAddress,
+ // End of shared entries.
+ DRT_GetThreadForNativeCallback,
+ // End of isolate-only entries.
};
- static intptr_t RelocationIndex(Relocation reloc) {
+ static constexpr intptr_t kVmEntryCount =
+ static_cast<intptr_t>(Relocation::InstructionsRelocatedAddress) + 1;
+
+ static constexpr intptr_t kIsolateEntryCount =
+ static_cast<intptr_t>(Relocation::DRT_GetThreadForNativeCallback) + 1;
+
+ static constexpr intptr_t RelocationIndex(Relocation reloc) {
return static_cast<intptr_t>(reloc);
}
- static void Initialize(Thread* current, uword* bss);
+ static void Initialize(Thread* current, uword* bss, bool vm);
+
+ // Currently only used externally by LoadedElf::ResolveSymbols() to set the
+ // relocated address without changing the embedder interface.
+ static void InitializeBSSEntry(BSS::Relocation relocation,
+ uword new_value,
+ uword* bss_start);
};
} // namespace dart
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index ec53422..d97b37d 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -4739,6 +4739,19 @@
delete[] clusters_by_cid_;
}
+void Serializer::FlushBytesWrittenToRoot() {
+#if defined(DART_PRECOMPILER)
+ if (profile_writer_ != nullptr) {
+ ASSERT(object_currently_writing_.id_ == 0);
+ // All bytes between objects are attributed into root node.
+ profile_writer_->AttributeBytesTo(
+ V8SnapshotProfileWriter::ArtificialRootId(),
+ stream_.Position() - object_currently_writing_.stream_start_);
+ object_currently_writing_.stream_start_ = stream_.Position();
+ }
+#endif
+}
+
void Serializer::TraceStartWritingObject(const char* type,
ObjectPtr obj,
StringPtr name) {
@@ -4765,6 +4778,7 @@
name_str = str.ToCString();
}
+ FlushBytesWrittenToRoot();
object_currently_writing_.object_ = obj;
object_currently_writing_.id_ = id;
object_currently_writing_.stream_start_ = stream_.Position();
@@ -4780,6 +4794,7 @@
{V8SnapshotProfileWriter::kSnapshot, object_currently_writing_.id_},
stream_.Position() - object_currently_writing_.stream_start_);
object_currently_writing_ = ProfilingObject();
+ object_currently_writing_.stream_start_ = stream_.Position();
}
}
@@ -5606,6 +5621,8 @@
Write<int32_t>(kSectionMarker);
#endif
+ FlushBytesWrittenToRoot();
+
PrintSnapshotSizes();
// Note we are not clearing the object id table. The full ref table
@@ -5670,9 +5687,10 @@
WriteRootRef(*p, kObjectStoreFieldNames[p - from]);
}
+ FlushBytesWrittenToRoot();
// The dispatch table is serialized only for precompiled snapshots.
WriteDispatchTable(dispatch_table_entries);
-
+ object_currently_writing_.stream_start_ = stream_.Position();
#if defined(DART_PRECOMPILER)
// If any bytes were written for the dispatch table, add it to the profile.
if (dispatch_table_size_ > 0 && profile_writer_ != nullptr) {
@@ -6647,6 +6665,19 @@
deserializer.ReadVMSnapshot();
+#if defined(DART_PRECOMPILED_RUNTIME)
+ // Initialize entries in the VM portion of the BSS segment.
+ ASSERT(Snapshot::IncludesCode(kind_));
+ Image image(instructions_image_);
+ if (image.bss_offset() != 0) {
+ // The const cast is safe because we're translating from the start of the
+ // instructions (read-only) to the start of the BSS (read-write).
+ uword* const bss_start = const_cast<uword*>(reinterpret_cast<const uword*>(
+ instructions_image_ + image.bss_offset()));
+ BSS::Initialize(thread_, bss_start, /*vm=*/true);
+ }
+#endif // defined(DART_PRECOMPILED_RUNTIME)
+
return ApiError::null();
}
@@ -6714,7 +6745,7 @@
}
}
- // Initialize symbols in the BSS, if present.
+ // Initialize entries in the isolate portion of the BSS segment.
ASSERT(Snapshot::IncludesCode(kind_));
Image image(instructions_image_);
if (image.bss_offset() != 0) {
@@ -6722,7 +6753,7 @@
// instructions (read-only) to the start of the BSS (read-write).
uword* const bss_start = const_cast<uword*>(reinterpret_cast<const uword*>(
instructions_image_ + image.bss_offset()));
- BSS::Initialize(thread_, bss_start);
+ BSS::Initialize(thread_, bss_start, /*vm=*/false);
}
#endif // defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index ddf07cb..bc86035 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -253,6 +253,7 @@
WriteStream* stream() { return &stream_; }
intptr_t bytes_written() { return stream_.bytes_written(); }
+ void FlushBytesWrittenToRoot();
void TraceStartWritingObject(const char* type, ObjectPtr obj, StringPtr name);
void TraceEndWritingObject();
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 512537e..20c0e5e 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -52,7 +52,7 @@
" i = 10; s1 = 'abcd'; k = 20; s2 = 'B'; s3 = 'C';"
" func(i, k);"
" return i + k; }"
- " static int moo() {"
+ " static void moo() {"
" var i = A.foo();"
" if (i != 30) throw '$i != 30';"
" }\n"
diff --git a/runtime/vm/compiler/backend/bce_test.cc b/runtime/vm/compiler/backend/bce_test.cc
index 44bc798..4567e63 100644
--- a/runtime/vm/compiler/backend/bce_test.cc
+++ b/runtime/vm/compiler/backend/bce_test.cc
@@ -145,7 +145,7 @@
const char* kScriptChars =
R"(
foo(int i) {
- var l = new List<int>(3);
+ var l = List<int>.filled(3, 0);
return l[i % 3] ?? l[i % (-3)];
}
main() {
@@ -278,7 +278,7 @@
const char* kScriptChars =
R"(
List<int> foo(int count) {
- var x = new List<int>(count);
+ var x = new List<int>.filled(count, 42);
for (int i = 0; i < count; i++) {
x[i] = 0;
}
@@ -291,7 +291,7 @@
foo(100);
}
)";
- TestScriptJIT(kScriptChars, 2, 0);
+ TestScriptJIT(kScriptChars, 2, 1);
}
} // namespace dart
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index c20199f..67bc54f 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -1582,7 +1582,6 @@
for (PhiIterator it(join); !it.Done(); it.Advance()) {
auto phi = it.Current();
if (TransformDefinition(phi)) {
- phi->UnuseAllInputs();
it.RemoveCurrentFromGraph();
}
}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 6c7297f..49ba718 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -2231,8 +2231,26 @@
for (BlockIterator block_it = reverse_postorder_iterator(); !block_it.Done();
block_it.Advance()) {
- for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
- it.Advance()) {
+ BlockEntryInstr* const block = block_it.Current();
+ if (auto join = block->AsJoinEntry()) {
+ for (PhiIterator it(join); !it.Done(); it.Advance()) {
+ PhiInstr* current = it.Current();
+ if (current->HasUnmatchedInputRepresentations()) {
+ // Can't canonicalize this instruction until all conversions for its
+ // inputs are inserted.
+ continue;
+ }
+
+ Definition* replacement = current->Canonicalize(this);
+ ASSERT(replacement != nullptr);
+ if (replacement != current) {
+ current->ReplaceUsesWith(replacement);
+ it.RemoveCurrentFromGraph();
+ changed = true;
+ }
+ }
+ }
+ for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
if (current->HasUnmatchedInputRepresentations()) {
// Can't canonicalize this instruction until all conversions for its
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index f0e0620..2808975 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -5477,8 +5477,11 @@
}
Definition* PhiInstr::GetReplacementForRedundantPhi() const {
- ASSERT(InputCount() > 1);
Definition* first = InputAt(0)->definition();
+ if (InputCount() == 1) {
+ return first;
+ }
+ ASSERT(InputCount() > 1);
Definition* first_origin = first->OriginalDefinition();
bool look_for_redefinition = false;
for (intptr_t i = 1; i < InputCount(); ++i) {
@@ -5516,6 +5519,19 @@
}
}
+Definition* PhiInstr::Canonicalize(FlowGraph* flow_graph) {
+ Definition* replacement = GetReplacementForRedundantPhi();
+ return (replacement != nullptr) ? replacement : this;
+}
+
+// Removes current phi from graph and sets current to previous phi.
+void PhiIterator::RemoveCurrentFromGraph() {
+ Current()->UnuseAllInputs();
+ (*phis_)[index_] = phis_->Last();
+ phis_->RemoveLast();
+ --index_;
+}
+
Instruction* CheckConditionInstr::Canonicalize(FlowGraph* graph) {
if (StrictCompareInstr* strict_compare = comparison()->AsStrictCompare()) {
if ((InputAt(0)->definition()->OriginalDefinition() ==
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 1e7e67e..9376cab 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -1776,11 +1776,7 @@
PhiInstr* Current() const { return (*phis_)[index_]; }
// Removes current phi from graph and sets current to previous phi.
- void RemoveCurrentFromGraph() {
- (*phis_)[index_] = phis_->Last();
- phis_->RemoveLast();
- --index_;
- }
+ void RemoveCurrentFromGraph();
private:
ZoneGrowableArray<PhiInstr*>* phis_;
@@ -2441,6 +2437,8 @@
// The replacement is selected among values redefined by inputs.
Definition* GetReplacementForRedundantPhi() const;
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
PRINT_TO_SUPPORT
enum ReceiverType { kUnknownReceiver = -1, kNotReceiver = 0, kReceiver = 1 };
diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc
index e764780..ad763a3 100644
--- a/runtime/vm/compiler/backend/il_test.cc
+++ b/runtime/vm/compiler/backend/il_test.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "platform/utils.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/unit_test.h"
@@ -45,26 +46,28 @@
}
ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) {
- const char* kScript =
- R"(
+ const char* tag = (FLAG_null_safety == kNullSafetyOptionStrong) ? "?" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class Container<T> {
operator []=(var index, var value) {
return data[index] = value;
}
- List<T> data = new List<T>()..length = 10;
+ List<T%s> data = List<T%s>.filled(10, null);
}
- Container<int> x = new Container<int>();
+ Container<int> x = Container<int>();
foo() {
for (int i = 0; i < 10; ++i) {
x[i] = i;
}
}
- )";
+ )", tag, tag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
const auto& function = Function::Handle(GetFunction(root_library, "foo"));
Invoke(root_library, "foo");
@@ -128,7 +131,9 @@
}
ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) {
- const char* kScript = R"(
+ const char* tag = (FLAG_null_safety == kNullSafetyOptionStrong) ? "?" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class Bar {
var f;
var g;
@@ -140,7 +145,7 @@
f3() {
return () { };
}
- f4<T>({T value}) {
+ f4<T>({T%s value}) {
return () { return value; };
}
main() {
@@ -149,8 +154,11 @@
f3();
f4();
}
- )";
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ )",
+ tag), std::free);
+ // clang-format on
+
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
RunInitializingStoresTest(root_library, "f1", CompilerPass::kJIT,
diff --git a/runtime/vm/compiler/backend/reachability_fence_test.cc b/runtime/vm/compiler/backend/reachability_fence_test.cc
index 782bc02..d0e6e8f 100644
--- a/runtime/vm/compiler/backend/reachability_fence_test.cc
+++ b/runtime/vm/compiler/backend/reachability_fence_test.cc
@@ -15,14 +15,19 @@
namespace dart {
ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Simple) {
- const char* kScript =
- R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* nullAssertTag = null_safety ? "!" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ R"(
import 'dart:_internal' show reachabilityFence;
int someGlobal = 0;
class A {
- int a;
+ int%s a;
}
void someFunction(int arg) {
@@ -31,12 +36,14 @@
main() {
final object = A()..a = 10;
- someFunction(object.a);
+ someFunction(object.a%s);
reachabilityFence(object);
}
- )";
+ )",
+ nullableTag, nullAssertTag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
@@ -71,14 +78,18 @@
}
ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Loop) {
- const char* kScript =
- R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* nullAssertTag = null_safety ? "!" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
import 'dart:_internal' show reachabilityFence;
int someGlobal = 0;
class A {
- int a;
+ int%s a;
}
@pragma('vm:never-inline')
@@ -93,13 +104,14 @@
main() {
final object = makeSomeA();
for(int i = 0; i < 100000; i++) {
- someFunction(object.a);
+ someFunction(object.a%s);
reachabilityFence(object);
}
}
- )";
+ )", nullableTag, nullAssertTag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
@@ -134,14 +146,18 @@
}
ISOLATE_UNIT_TEST_CASE(ReachabilityFence_NoCanonicalize) {
- const char* kScript =
- R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* nullAssertTag = null_safety ? "!" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
import 'dart:_internal' show reachabilityFence;
int someGlobal = 0;
class A {
- int a;
+ int%s a;
}
@pragma('vm:never-inline')
@@ -157,15 +173,16 @@
final object = makeSomeA();
reachabilityFence(object);
for(int i = 0; i < 100000; i++) {
- someFunction(object.a);
+ someFunction(object.a%s);
reachabilityFence(object);
}
reachabilityFence(object);
reachabilityFence(object);
}
- )";
+ )", nullableTag, nullAssertTag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 45c4b24..c211abb 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3683,14 +3683,6 @@
if (FLAG_trace_optimization) {
THR_Print("Removing dead phi v%" Pd "\n", phi->ssa_temp_index());
}
- } else if (auto* replacement = phi->GetReplacementForRedundantPhi()) {
- phi->ReplaceUsesWith(replacement);
- phi->UnuseAllInputs();
- (*join->phis_)[i] = nullptr;
- if (FLAG_trace_optimization) {
- THR_Print("Removing redundant phi v%" Pd "\n",
- phi->ssa_temp_index());
- }
} else {
(*join->phis_)[to_index++] = phi;
}
@@ -3782,7 +3774,6 @@
for (PhiIterator it(join); !it.Done(); it.Advance()) {
PhiInstr* current = it.Current();
if (!live.Contains(current->ssa_temp_index())) {
- current->UnuseAllInputs();
it.RemoveCurrentFromGraph();
}
}
@@ -3799,7 +3790,6 @@
continue;
}
}
- current->UnuseAllInputs();
it.RemoveCurrentFromGraph();
}
}
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index fdbd957..5027e27 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -905,7 +905,7 @@
const char* kScript = R"(
class Bar {
Bar() { a = null; }
- Object a;
+ dynamic a;
}
Bar foo() {
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index fcf1393..119b2f3 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -20,12 +20,9 @@
false,
"Generate always trampolines (for testing purposes).");
-// The trampolines will be disguised as FreeListElement objects, with a 1-word
-// object header in front of the jump code.
-const intptr_t kOffsetInTrampoline = kWordSize;
-const intptr_t kTrampolineSize = Utils::RoundUp(
- kOffsetInTrampoline + PcRelativeTrampolineJumpPattern::kLengthInBytes,
- kObjectAlignment);
+const intptr_t kTrampolineSize =
+ Utils::RoundUp(PcRelativeTrampolineJumpPattern::kLengthInBytes,
+ ImageWriter::kBareInstructionsAlignment);
CodeRelocator::CodeRelocator(Thread* thread,
GrowableArray<CodePtr>* code_objects,
@@ -402,8 +399,7 @@
FindDestinationInText(callee, unresolved_trampoline->offset_into_target);
const int32_t distance = destination_text - trampoline_text_offset;
- PcRelativeTrampolineJumpPattern pattern(trampoline_start +
- kOffsetInTrampoline);
+ PcRelativeTrampolineJumpPattern pattern(trampoline_start);
pattern.Initialize();
pattern.set_distance(distance);
ASSERT(pattern.distance() == distance);
@@ -467,25 +463,6 @@
return destination_.raw();
}
-static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
- intptr_t trampoline_length) {
- uint32_t tags = 0;
-#if defined(IS_SIMARM_X64)
- // Account for difference in kObjectAlignment between host and target.
- tags = ObjectLayout::SizeTag::update(trampoline_length * 2, tags);
-#else
- tags = ObjectLayout::SizeTag::update(trampoline_length, tags);
-#endif
- tags = ObjectLayout::ClassIdTag::update(kFreeListElement, tags);
- tags = ObjectLayout::OldBit::update(true, tags);
- tags = ObjectLayout::OldAndNotMarkedBit::update(true, tags);
- tags = ObjectLayout::OldAndNotRememberedBit::update(true, tags);
- tags = ObjectLayout::NewBit::update(false, tags);
-
- auto header_word = reinterpret_cast<uintptr_t*>(trampoline_bytes);
- *header_word = tags;
-}
-
void CodeRelocator::BuildTrampolinesForAlmostOutOfRangeCalls() {
while (!all_unresolved_calls_.IsEmpty()) {
UnresolvedCall* unresolved_call = all_unresolved_calls_.First();
@@ -497,8 +474,7 @@
const intptr_t future_boundary =
next_text_offset_ + max_instructions_size_ +
kTrampolineSize *
- (unresolved_calls_by_destination_.Length() + max_calls_) +
- kOffsetInTrampoline;
+ (unresolved_calls_by_destination_.Length() + max_calls_);
if (IsTargetInRangeFor(unresolved_call, future_boundary) &&
!FLAG_always_generate_trampolines_for_testing) {
break;
@@ -530,14 +506,19 @@
// [ImageWriter], which will eventually write out the bytes and delete the
// buffer.
auto trampoline_bytes = new uint8_t[kTrampolineSize];
- memset(trampoline_bytes, 0x00, kTrampolineSize);
+ ASSERT((kTrampolineSize % compiler::target::kWordSize) == 0);
+ for (uint8_t* cur = trampoline_bytes;
+ cur < trampoline_bytes + kTrampolineSize;
+ cur += compiler::target::kWordSize) {
+ *reinterpret_cast<compiler::target::uword*>(cur) =
+ kBreakInstructionFiller;
+ }
auto unresolved_trampoline = new UnresolvedTrampoline{
unresolved_call->callee,
unresolved_call->offset_into_target,
trampoline_bytes,
- next_text_offset_ + kOffsetInTrampoline,
+ next_text_offset_,
};
- MarkAsFreeListElement(trampoline_bytes, kTrampolineSize);
AddTrampolineToText(callee, trampoline_bytes, kTrampolineSize);
EnqueueUnresolvedTrampoline(unresolved_trampoline);
trampoline_text_offset = unresolved_trampoline->text_offset;
diff --git a/runtime/vm/compiler/write_barrier_elimination_test.cc b/runtime/vm/compiler/write_barrier_elimination_test.cc
index 737e213..53b16e8 100644
--- a/runtime/vm/compiler/write_barrier_elimination_test.cc
+++ b/runtime/vm/compiler/write_barrier_elimination_test.cc
@@ -13,28 +13,32 @@
ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_JoinSuccessors) {
DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true);
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* nullAssertTag = null_safety ? "!" : "";
// This is a regression test for a bug where we were using
// JoinEntry::SuccessorCount() to determine the number of outgoing blocks
// from the join block. JoinEntry::SuccessorCount() is in fact always 0;
// JoinEntry::last_instruction()->SuccessorCount() should be used instead.
- const char* kScript =
- R"(
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr, R"(
class C {
- int value;
- C next;
- C prev;
+ int%s value;
+ C%s next;
+ C%s prev;
}
@pragma("vm:never-inline")
fn() {}
foo(int x) {
- C prev = C();
- C next;
+ C%s prev = C();
+ C%s next;
while (x --> 0) {
next = C();
- next.prev = prev;
+ next%s.prev = prev;
prev?.next = next;
prev = next;
fn();
@@ -43,9 +47,12 @@
}
main() { foo(10); }
- )";
+ )",
+ nullableTag, nullableTag, nullableTag, nullableTag,
+ nullableTag, nullAssertTag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
@@ -77,15 +84,17 @@
ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_AtLeastOnce) {
DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true);
-
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
// Ensure that we process every block at least once during the analysis
// phase so that the out-sets will be initialized. If we don't process
// each block at least once, the store "c.next = n" will be marked
// NoWriteBarrier.
- const char* kScript =
- R"(
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ R"(
class C {
- C next;
+ %s C next;
}
@pragma("vm:never-inline")
@@ -102,9 +111,9 @@
}
main() { foo(0); foo(10); }
- )";
-
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ )", lateTag), std::free);
+ // clang-format on
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
@@ -133,13 +142,18 @@
ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_Arrays) {
DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true);
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* lateTag = null_safety ? "late" : "";
+
// Test that array allocations are not considered usable after a
// may-trigger-GC instruction (in this case CheckStackOverflow), unlike
// normal allocations, which are only interruped by a Dart call.
- const char* kScript =
- R"(
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class C {
- C next;
+ %s C next;
}
@pragma("vm:never-inline")
@@ -148,7 +162,7 @@
foo(int x) {
C c = C();
C n = C();
- List<C> array = List<C>(1);
+ List<C%s> array = List<C%s>.filled(1, null);
while (x --> 0) {
c.next = n;
n = c;
@@ -159,9 +173,10 @@
}
main() { foo(10); }
- )";
+ )", lateTag, nullableTag, nullableTag), std::free);
+ // clang-format on
- const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& root_library = Library::Handle(LoadTestScript(kScript.get()));
Invoke(root_library, "main");
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 24eea81..f8467df 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -3033,12 +3033,17 @@
return store->type_argument_legacy_string();
}
UNREACHABLE();
- return NULL;
+ return TypeArguments::null();
}
DART_EXPORT Dart_Handle Dart_NewListOf(Dart_CoreType_Id element_type_id,
intptr_t length) {
DARTSCOPE(Thread::Current());
+ if (T->isolate()->null_safety() && element_type_id != Dart_CoreType_Dynamic) {
+ return Api::NewError(
+ "Cannot use legacy types with --null-safety enabled. "
+ "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead.");
+ }
CHECK_LENGTH(length, Array::kMaxElements);
CHECK_CALLBACK_STATE(T);
const Array& arr = Array::Handle(Z, Array::New(length));
@@ -5584,6 +5589,11 @@
Dart_Handle class_name,
intptr_t number_of_type_arguments,
Dart_Handle* type_arguments) {
+ if (Thread::Current()->isolate()->null_safety()) {
+ return Api::NewError(
+ "Cannot use legacy types with --null-safety enabled. "
+ "Use Dart_GetNullableType or Dart_GetNonNullableType instead.");
+ }
return GetTypeCommon(library, class_name, number_of_type_arguments,
type_arguments, Nullability::kLegacy);
}
@@ -6520,24 +6530,33 @@
Dwarf* debug_dwarf =
generate_debug ? new (Z) Dwarf(Z, nullptr, debug_elf) : nullptr;
+ // Here, both VM and isolate will be compiled into a single snapshot.
+ // In assembly generation, each serialized text section gets a separate
+ // pointer into the BSS segment and BSS slots are created for each, since
+ // we may not serialize both VM and isolate. Here, we always serialize both,
+ // so make a BSS segment large enough for both, with the VM entries coming
+ // first.
+ auto const isolate_offset = BSS::kVmEntryCount * compiler::target::kWordSize;
+ auto const bss_size =
+ isolate_offset + BSS::kIsolateEntryCount * compiler::target::kWordSize;
// Note that the BSS section must come first because it cannot be placed in
// between any two non-writable segments, due to a bug in Jelly Bean's ELF
// loader. See also Elf::WriteProgramTable().
- const intptr_t bss_base =
- elf->AddBSSData("_kDartBSSData", sizeof(compiler::target::uword));
+ const intptr_t vm_bss_base = elf->AddBSSData("_kDartBSSData", bss_size);
+ const intptr_t isolate_bss_base = vm_bss_base + isolate_offset;
// Add the BSS section to the separately saved debugging information, even
// though there will be no code in it to relocate, since it precedes the
// .text sections and thus affects their virtual addresses.
if (debug_dwarf != nullptr) {
- debug_elf->AddBSSData("_kDartBSSData", sizeof(compiler::target::uword));
+ debug_elf->AddBSSData("_kDartBSSData", bss_size);
}
BlobImageWriter vm_image_writer(T, &vm_snapshot_instructions_buffer,
ApiReallocate, kInitialSize, debug_dwarf,
- bss_base, elf, elf_dwarf);
+ vm_bss_base, elf, elf_dwarf);
BlobImageWriter isolate_image_writer(T, &isolate_snapshot_instructions_buffer,
ApiReallocate, kInitialSize, debug_dwarf,
- bss_base, elf, elf_dwarf);
+ isolate_bss_base, elf, elf_dwarf);
FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer,
&isolate_snapshot_data_buffer, ApiReallocate,
&vm_image_writer, &isolate_image_writer);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 4f1551d..6b501e6 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1079,7 +1079,7 @@
EXPECT_VALID(result);
EXPECT(is_static);
- Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL);
+ Dart_Handle klass = Dart_GetNonNullableType(lib, NewString("Foo"), 0, NULL);
EXPECT_VALID(klass);
Dart_Handle instance = Dart_Allocate(klass);
@@ -1174,7 +1174,7 @@
TEST_CASE(DartAPI_ClassLibrary) {
Dart_Handle lib = Dart_LookupLibrary(NewString("dart:core"));
EXPECT_VALID(lib);
- Dart_Handle type = Dart_GetType(lib, NewString("int"), 0, NULL);
+ Dart_Handle type = Dart_GetNonNullableType(lib, NewString("int"), 0, NULL);
EXPECT_VALID(type);
Dart_Handle result = Dart_ClassLibrary(type);
EXPECT_VALID(result);
@@ -1695,7 +1695,7 @@
TEST_CASE(DartAPI_ListAccess) {
const char* kScriptChars =
"List testMain() {"
- " List a = new List();"
+ " List a = List.empty(growable: true);"
" a.add(10);"
" a.add(20);"
" a.add(30);"
@@ -4034,7 +4034,9 @@
EXPECT_VALID(double_type);
EXPECT_VALID(Dart_ListSetAt(type_args, 1, double_type));
Dart_Handle myclass0_type =
- Dart_GetType(lib, NewString("MyClass0"), 2, &type_args);
+ (FLAG_null_safety == kNullSafetyOptionStrong)
+ ? Dart_GetNonNullableType(lib, NewString("MyClass0"), 2, &type_args)
+ : Dart_GetType(lib, NewString("MyClass0"), 2, &type_args);
EXPECT_VALID(myclass0_type);
type_args = Dart_NewList(2);
@@ -4046,7 +4048,9 @@
EXPECT_VALID(list_type);
EXPECT_VALID(Dart_ListSetAt(type_args, 1, list_type));
Dart_Handle myclass1_type =
- Dart_GetType(lib, NewString("MyClass1"), 2, &type_args);
+ (FLAG_null_safety == kNullSafetyOptionStrong)
+ ? Dart_GetNonNullableType(lib, NewString("MyClass1"), 2, &type_args)
+ : Dart_GetType(lib, NewString("MyClass1"), 2, &type_args);
EXPECT_VALID(myclass1_type);
// Now create objects of the type and validate the object type matches
@@ -4220,7 +4224,7 @@
// Shared setup.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("Fields"), 0, NULL);
+ Dart_Handle type = Dart_GetNonNullableType(lib, NewString("Fields"), 0, NULL);
EXPECT_VALID(type);
Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL);
EXPECT_VALID(instance);
@@ -4413,7 +4417,9 @@
}
TEST_CASE(DartAPI_SetField_BadType) {
- const char* kScriptChars = "int foo;\n";
+ const char* kScriptChars = (FLAG_null_safety == kNullSafetyOptionStrong)
+ ? "late int foo;\n"
+ : "int foo;\n";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_Handle name = NewString("foo");
Dart_Handle result = Dart_SetField(lib, name, Dart_True());
@@ -4435,22 +4441,29 @@
}
TEST_CASE(DartAPI_InjectNativeFields2) {
- const char* kScriptChars =
- "class NativeFields extends NativeFieldsWrapper {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- "}\n"
- "NativeFields testMain() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " return obj;\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class NativeFields extends NativeFieldsWrapper {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ "}\n"
+ "NativeFields testMain() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " return obj;\n"
+ "}\n",
+ nullableTag), std::free);
+ // clang-format on
+
Dart_Handle result;
// Create a test library and Load up a test script in it.
Dart_Handle lib =
- TestCase::LoadTestScript(kScriptChars, NULL, USER_TEST_URI, false);
+ TestCase::LoadTestScript(kScriptChars.get(), NULL, USER_TEST_URI, false);
// Invoke a function which returns an object of type NativeFields.
result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
@@ -4462,24 +4475,31 @@
}
TEST_CASE(DartAPI_InjectNativeFields3) {
- const char* kScriptChars =
- "import 'dart:nativewrappers';"
- "class NativeFields extends NativeFieldWrapperClass2 {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- "}\n"
- "NativeFields testMain() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " return obj;\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "import 'dart:nativewrappers';"
+ "class NativeFields extends NativeFieldWrapperClass2 {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld2;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ "}\n"
+ "NativeFields testMain() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " return obj;\n"
+ "}\n",
+ nullableTag), std::free);
+ // clang-format on
Dart_Handle result;
const int kNumNativeFields = 2;
// Load up a test script in the test library.
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, native_field_lookup);
+ Dart_Handle lib =
+ TestCase::LoadTestScript(kScriptChars.get(), native_field_lookup);
// Invoke a function which returns an object of type NativeFields.
result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
@@ -4504,22 +4524,27 @@
}
TEST_CASE(DartAPI_InjectNativeFields4) {
- const char* kScriptChars =
- "import 'dart:nativewrappers';"
- "class NativeFields extends NativeFieldWrapperClass2 {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- "}\n"
- "NativeFields testMain() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " return obj;\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class NativeFields extends NativeFieldsWrapperClass2 {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ "}\n"
+ "NativeFields testMain() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " return obj;\n"
+ "}\n",
+ nullableTag), std::free);
+ // clang-format on
Dart_Handle result;
// Load up a test script in the test library.
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(), NULL);
// Invoke a function which returns an object of type NativeFields.
result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
@@ -4585,27 +4610,36 @@
}
TEST_CASE(DartAPI_TestNativeFieldsAccess) {
- const char* kScriptChars =
- "import 'dart:nativewrappers';"
- "class NativeFields extends NativeFieldWrapperClass2 {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- " int initNativeFlds() native 'TestNativeFieldsAccess_init';\n"
- " int accessNativeFlds(int i) native 'TestNativeFieldsAccess_access';\n"
- "}\n"
- "NativeFields testMain() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " obj.initNativeFlds();\n"
- " obj.accessNativeFlds(null);\n"
- " return obj;\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(
+ nullptr,
+ "import 'dart:nativewrappers';"
+ "class NativeFields extends NativeFieldWrapperClass2 {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld2;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ " int%s initNativeFlds() native 'TestNativeFieldsAccess_init';\n"
+ " int%s accessNativeFlds(int%s i) native "
+ "'TestNativeFieldsAccess_access';\n"
+ "}\n"
+ "NativeFields testMain() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " obj.initNativeFlds();\n"
+ " obj.accessNativeFlds(null);\n"
+ " return obj;\n"
+ "}\n",
+ nullableTag, nullableTag, nullableTag, nullableTag),
+ std::free);
+ // clang-format on
// Load up a test script in the test library.
- Dart_Handle lib =
- TestCase::LoadTestScript(kScriptChars, TestNativeFieldsAccess_lookup);
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(),
+ TestNativeFieldsAccess_lookup);
// Invoke a function which returns an object of type NativeFields.
Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
@@ -4717,22 +4751,30 @@
}
TEST_CASE(DartAPI_ImplicitNativeFieldAccess) {
- const char* kScriptChars =
- "import 'dart:nativewrappers';"
- "class NativeFields extends NativeFieldWrapperClass4 {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld0;\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- "}\n"
- "NativeFields testMain() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " return obj;\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "import 'dart:nativewrappers';"
+ "class NativeFields extends NativeFieldWrapperClass4 {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int%s fld0;\n"
+ " int fld1;\n"
+ " final int fld2;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ "}\n"
+ "NativeFields testMain() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " return obj;\n"
+ "}\n",
+ nullableTag, nullableTag),
+ std::free);
+ // clang-format on
// Load up a test script in the test library.
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, native_field_lookup);
+ Dart_Handle lib =
+ TestCase::LoadTestScript(kScriptChars.get(), native_field_lookup);
// Invoke a function which returns an object of type NativeFields.
Dart_Handle retobj = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
@@ -4743,26 +4785,35 @@
}
TEST_CASE(DartAPI_NegativeNativeFieldAccess) {
- const char* kScriptChars =
- "class NativeFields {\n"
- " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " static int fld3;\n"
- " static const int fld4 = 10;\n"
- "}\n"
- "NativeFields testMain1() {\n"
- " NativeFields obj = new NativeFields(10, 20);\n"
- " return obj;\n"
- "}\n"
- "Function testMain2() {\n"
- " return () {};\n"
- "}\n";
+ bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "import 'dart:nativewrappers';\n"
+ "class NativeFields {\n"
+ " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld2;\n"
+ " static int%s fld3;\n"
+ " static const int fld4 = 10;\n"
+ "}\n"
+ "NativeFields testMain1() {\n"
+ " NativeFields obj = new NativeFields(10, 20);\n"
+ " return obj;\n"
+ "}\n"
+ "Function testMain2() {\n"
+ " return () {};\n"
+ "}\n",
+ nullableTag),
+ std::free);
+ // clang-format on
+
Dart_Handle result;
CHECK_API_SCOPE(thread);
// Create a test library and Load up a test script in it.
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(), NULL);
// Invoke a function which returns an object of type NativeFields.
Dart_Handle retobj = Dart_Invoke(lib, NewString("testMain1"), 0, NULL);
@@ -4823,7 +4874,8 @@
Dart_Handle result;
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL);
EXPECT_VALID(type);
// Invoke a function which returns an object.
@@ -4865,7 +4917,8 @@
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL);
EXPECT_VALID(type);
result = Dart_GetField(type, NewString("fld2"));
@@ -4886,7 +4939,8 @@
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL);
EXPECT_VALID(type);
result = Dart_SetField(type, NewString("fld2"), Dart_NewInteger(13));
@@ -4927,9 +4981,11 @@
"}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("MyClass"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("MyClass"), 0, NULL);
EXPECT_VALID(type);
- Dart_Handle intf = Dart_GetType(lib, NewString("MyInterface"), 0, NULL);
+ Dart_Handle intf =
+ Dart_GetNonNullableType(lib, NewString("MyInterface"), 0, NULL);
EXPECT_VALID(intf);
Dart_Handle args[1];
args[0] = Dart_NewInteger(11);
@@ -5135,7 +5191,8 @@
// factories.
Dart_Handle core_lib = Dart_LookupLibrary(NewString("dart:core"));
EXPECT_VALID(core_lib);
- Dart_Handle list_type = Dart_GetType(core_lib, NewString("List"), 0, NULL);
+ Dart_Handle list_type =
+ Dart_GetNonNullableType(core_lib, NewString("List"), 0, NULL);
EXPECT_VALID(list_type);
const int kNumArgs = 1;
@@ -5156,16 +5213,21 @@
const int kNumArgs = 1;
Dart_Handle args[kNumArgs];
const char* str;
-
+ Dart_Handle result;
Dart_Handle string_list = Dart_NewListOf(Dart_CoreType_String, 1);
- EXPECT_VALID(string_list);
- args[0] = string_list;
- Dart_Handle result =
- Dart_Invoke(lib, NewString("expectListOfString"), kNumArgs, args);
- EXPECT_VALID(result);
- result = Dart_StringToCString(result, &str);
- EXPECT_VALID(result);
- EXPECT_STREQ("null", str);
+ if (!Dart_IsError(string_list)) {
+ args[0] = string_list;
+ Dart_Handle result =
+ Dart_Invoke(lib, NewString("expectListOfString"), kNumArgs, args);
+ EXPECT_VALID(result);
+ result = Dart_StringToCString(result, &str);
+ EXPECT_VALID(result);
+ EXPECT_STREQ("null", str);
+ } else {
+ EXPECT_ERROR(string_list,
+ "Cannot use legacy types with --null-safety enabled. "
+ "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead.");
+ }
Dart_Handle dynamic_list = Dart_NewListOf(Dart_CoreType_Dynamic, 1);
EXPECT_VALID(dynamic_list);
@@ -5176,12 +5238,17 @@
EXPECT_STREQ("null", str);
Dart_Handle int_list = Dart_NewListOf(Dart_CoreType_Int, 1);
- EXPECT_VALID(int_list);
- args[0] = int_list;
- result = Dart_Invoke(lib, NewString("expectListOfInt"), kNumArgs, args);
- EXPECT_VALID(result);
- result = Dart_StringToCString(result, &str);
- EXPECT_STREQ("null", str);
+ if (!Dart_IsError(int_list)) {
+ args[0] = int_list;
+ result = Dart_Invoke(lib, NewString("expectListOfInt"), kNumArgs, args);
+ EXPECT_VALID(result);
+ result = Dart_StringToCString(result, &str);
+ EXPECT_STREQ("null", str);
+ } else {
+ EXPECT_ERROR(int_list,
+ "Cannot use legacy types with --null-safety enabled. "
+ "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead.");
+ }
}
TEST_CASE(DartAPI_NewListOfType) {
@@ -5197,7 +5264,8 @@
"void expectListOfNever(List<Never> _) {}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle zxhandle_type = Dart_GetType(lib, NewString("ZXHandle"), 0, NULL);
+ Dart_Handle zxhandle_type =
+ Dart_GetNullableType(lib, NewString("ZXHandle"), 0, NULL);
EXPECT_VALID(zxhandle_type);
Dart_Handle zxhandle = Dart_New(zxhandle_type, Dart_Null(), 0, NULL);
@@ -5209,7 +5277,7 @@
EXPECT_VALID(Dart_ListSetAt(zxhandle_list, 0, zxhandle));
Dart_Handle readresult_type =
- Dart_GetType(lib, NewString("ChannelReadResult"), 0, NULL);
+ Dart_GetNonNullableType(lib, NewString("ChannelReadResult"), 0, NULL);
EXPECT_VALID(zxhandle_type);
const int kNumArgs = 1;
@@ -5228,7 +5296,7 @@
EXPECT_VALID(dart_core);
Dart_Handle string_type =
- Dart_GetType(dart_core, NewString("String"), 0, NULL);
+ Dart_GetNonNullableType(dart_core, NewString("String"), 0, NULL);
EXPECT_VALID(string_type);
Dart_Handle string_list = Dart_NewListOfType(string_type, 0);
EXPECT_VALID(string_list);
@@ -5293,7 +5361,7 @@
EXPECT(Dart_IdentityEquals(result, zxhandle));
Dart_Handle readresult_type =
- Dart_GetType(lib, NewString("ChannelReadResult"), 0, NULL);
+ Dart_GetNonNullableType(lib, NewString("ChannelReadResult"), 0, NULL);
EXPECT_VALID(zxhandle_type);
const int kNumArgs = 1;
@@ -5355,7 +5423,8 @@
// Shared setup.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL);
EXPECT_VALID(type);
Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL);
EXPECT_VALID(instance);
@@ -5461,7 +5530,8 @@
// Shared setup.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL);
Dart_Handle result;
EXPECT_VALID(type);
Dart_Handle name = NewString("_staticMethod");
@@ -5554,7 +5624,8 @@
// Shared setup.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL);
EXPECT_VALID(type);
Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL);
EXPECT_VALID(instance);
@@ -5672,7 +5743,8 @@
// Create a test library and Load up a test script in it.
// The test library must have a dart: url so it can import dart:_internal.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL);
EXPECT_VALID(type);
// Invoke a function which returns an object.
@@ -5806,7 +5878,8 @@
static intptr_t native_arg_str_peer = 100;
static void NativeArgumentCreate(Dart_NativeArguments args) {
Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url()));
- Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("MyObject"), 0, NULL);
EXPECT_VALID(type);
// Allocate without a constructor.
@@ -6038,94 +6111,53 @@
const Dart_Handle name = NewString("Class");
// Lookup the legacy type for Class.
Dart_Handle type = Dart_GetType(lib, name, 0, NULL);
- EXPECT_VALID(type);
- bool result = false;
- EXPECT_VALID(Dart_IsLegacyType(type, &result));
- EXPECT(result);
+ Dart_Handle nonNullableType;
+ Dart_Handle nullableType;
+ if (Dart_IsError(type)) {
+ EXPECT_ERROR(
+ type,
+ "Cannot use legacy types with --null-safety enabled. "
+ "Use Dart_GetNullableType or Dart_GetNonNullableType instead.");
- // Legacy -> Nullable
- Dart_Handle nullableType = Dart_TypeToNullableType(type);
- EXPECT_VALID(nullableType);
- result = false;
- EXPECT_VALID(Dart_IsNullableType(nullableType, &result));
- EXPECT(result);
- EXPECT(Dart_IdentityEquals(nullableType,
- Dart_GetNullableType(lib, name, 0, nullptr)));
+ nonNullableType = Dart_GetNonNullableType(lib, name, 0, nullptr);
+ EXPECT_VALID(nonNullableType);
+ nullableType = Dart_GetNullableType(lib, name, 0, nullptr);
+ } else {
+ EXPECT_VALID(type);
+ bool result = false;
+ EXPECT_VALID(Dart_IsLegacyType(type, &result));
+ EXPECT(result);
- // Legacy -> Non-Nullable
- Dart_Handle nonNullableType = Dart_TypeToNonNullableType(type);
- EXPECT_VALID(nonNullableType);
- result = false;
- EXPECT_VALID(Dart_IsNonNullableType(nonNullableType, &result));
- EXPECT(result);
- EXPECT(Dart_IdentityEquals(nonNullableType,
- Dart_GetNonNullableType(lib, name, 0, nullptr)));
+ // Legacy -> Nullable
+ nullableType = Dart_TypeToNullableType(type);
+ EXPECT_VALID(nullableType);
+ result = false;
+ EXPECT_VALID(Dart_IsNullableType(nullableType, &result));
+ EXPECT(result);
+ EXPECT(Dart_IdentityEquals(nullableType,
+ Dart_GetNullableType(lib, name, 0, nullptr)));
+
+ // Legacy -> Non-Nullable
+ nonNullableType = Dart_TypeToNonNullableType(type);
+ EXPECT_VALID(nonNullableType);
+ result = false;
+ EXPECT_VALID(Dart_IsNonNullableType(nonNullableType, &result));
+ EXPECT(result);
+ EXPECT(Dart_IdentityEquals(nonNullableType,
+ Dart_GetNonNullableType(lib, name, 0, nullptr)));
+ }
// Nullable -> Non-Nullable
EXPECT(Dart_IdentityEquals(
nonNullableType,
Dart_TypeToNonNullableType(Dart_GetNullableType(lib, name, 0, nullptr))));
- // Nullable -> Non-Nullable
+ // Non-Nullable -> Nullable
EXPECT(Dart_IdentityEquals(
nullableType,
Dart_TypeToNullableType(Dart_GetNonNullableType(lib, name, 0, nullptr))));
}
-TEST_CASE(DartAPI_GetType) {
- const char* kScriptChars =
- "library testlib;\n"
- "class Class {\n"
- " static var name = 'Class';\n"
- "}\n"
- "\n"
- "class _Class {\n"
- " static var name = '_Class';\n"
- "}\n";
-
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-
- // Lookup a class.
- Dart_Handle type = Dart_GetType(lib, NewString("Class"), 0, NULL);
- EXPECT_VALID(type);
- bool result = false;
- EXPECT_VALID(Dart_IsLegacyType(type, &result));
- EXPECT(result);
- Dart_Handle name = Dart_GetField(type, NewString("name"));
- EXPECT_VALID(name);
- const char* name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(name, &name_cstr));
- EXPECT_STREQ("Class", name_cstr);
-
- // Lookup a private class.
- type = Dart_GetType(lib, NewString("_Class"), 0, NULL);
- EXPECT_VALID(type);
- result = false;
- EXPECT_VALID(Dart_IsLegacyType(type, &result));
- EXPECT(result);
- name = Dart_GetField(type, NewString("name"));
- EXPECT_VALID(name);
- name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(name, &name_cstr));
- EXPECT_STREQ("_Class", name_cstr);
-
- // Lookup a class that does not exist.
- type = Dart_GetType(lib, NewString("DoesNotExist"), 0, NULL);
- EXPECT(Dart_IsError(type));
- EXPECT_STREQ("Type 'DoesNotExist' not found in library 'testlib'.",
- Dart_GetError(type));
-
- // Lookup a class from an error library. The error propagates.
- type = Dart_GetType(Api::NewError("myerror"), NewString("Class"), 0, NULL);
- EXPECT(Dart_IsError(type));
- EXPECT_STREQ("myerror", Dart_GetError(type));
-
- // Lookup a type using an error class name. The error propagates.
- type = Dart_GetType(lib, Api::NewError("myerror"), 0, NULL);
- EXPECT(Dart_IsError(type));
- EXPECT_STREQ("myerror", Dart_GetError(type));
-}
-
TEST_CASE(DartAPI_GetNullableType) {
const char* kScriptChars =
"library testlib;\n"
@@ -6263,7 +6295,8 @@
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
// Fetch InstanceOfTest class.
- Dart_Handle type = Dart_GetType(lib, NewString("InstanceOfTest"), 0, NULL);
+ Dart_Handle type =
+ Dart_GetNonNullableType(lib, NewString("InstanceOfTest"), 0, NULL);
EXPECT_VALID(type);
// Invoke a function which returns an object of type InstanceOf..
@@ -6279,7 +6312,8 @@
EXPECT(is_instance);
// Fetch OtherClass and check if instanceOfTestObj is instance of it.
- Dart_Handle otherType = Dart_GetType(lib, NewString("OtherClass"), 0, NULL);
+ Dart_Handle otherType =
+ Dart_GetNonNullableType(lib, NewString("OtherClass"), 0, NULL);
EXPECT_VALID(otherType);
result = Dart_ObjectIsType(instanceOfTestObj, otherType, &is_instance);
@@ -6472,7 +6506,7 @@
result = Dart_FinalizeLoading(false);
EXPECT_VALID(result);
EXPECT(Dart_IsLibrary(lib));
- Dart_Handle type = Dart_GetType(lib, NewString("Test"), 0, NULL);
+ Dart_Handle type = Dart_GetNonNullableType(lib, NewString("Test"), 0, NULL);
EXPECT_VALID(type);
result = Dart_SetNativeResolver(Dart_Null(), &MyNativeResolver1, NULL);
@@ -8206,9 +8240,9 @@
"void main() {\n"
" var v;\n"
" for (var i = 0; i < 100; i++) {\n"
- " var t = new List();\n"
+ " var t = [];\n"
" for (var j = 0; j < 10000; j++) {\n"
- " t.add(new List(100));\n"
+ " t.add(List.filled(100, null));\n"
" }\n"
" v = t;\n"
" notifyIdle();\n"
@@ -8237,9 +8271,9 @@
"void main() {\n"
" var v;\n"
" for (var i = 0; i < 100; i++) {\n"
- " var t = new List();\n"
+ " var t = [];\n"
" for (var j = 0; j < 10000; j++) {\n"
- " t.add(new List(100));\n"
+ " t.add(List.filled(100, null));\n"
" }\n"
" v = t;\n"
" notifyIdle();\n"
@@ -8269,9 +8303,9 @@
"void main() {\n"
" var v;\n"
" for (var i = 0; i < 100; i++) {\n"
- " var t = new List();\n"
+ " var t = [];\n"
" for (var j = 0; j < 10000; j++) {\n"
- " t.add(new List(100));\n"
+ " t.add(List.filled(100, null));\n"
" }\n"
" v = t;\n"
" notifyLowMemory();\n"
@@ -8346,6 +8380,7 @@
if (!condition) {
throw 'Failed to validate InvokeVMServiceMethod() response.';
}
+ return false;
}
bool validateResult(Uint8List bytes) {
final map = json.decode(utf8.decode(bytes));
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 6ed8438..7fb427c4 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -642,22 +642,6 @@
AddSection(shstrtab_, ".shstrtab");
}
-// The VM segment comes after the program header segment and BSS segments,
-// both of which are a single page.
-static constexpr uword kVmSnapshotOffset = 2 * Elf::kPageSize;
-
-// Find the relocated base of the loaded ELF snapshot. Returns 0 if there is
-// no loaded ELF snapshot.
-uword Elf::SnapshotRelocatedBaseAddress(uword vm_start) {
- // We can't running from a loaded ELF snapshot if this is the case.
- if (vm_start < kVmSnapshotOffset) return 0;
-
- const Image vm_instructions_image(reinterpret_cast<const void*>(vm_start));
- if (!vm_instructions_image.compiled_to_elf()) return 0;
-
- return vm_start - kVmSnapshotOffset;
-}
-
void Elf::AddSection(Section* section, const char* name) {
ASSERT(section_table_file_size_ < 0);
ASSERT(!shstrtab_->HasBeenFinalized());
@@ -824,8 +808,6 @@
FinalizeProgramTable();
ComputeFileOffsets();
- ASSERT(VerifySegmentOrder());
-
// Finally, write the ELF file contents.
WriteHeader();
WriteProgramTable();
@@ -891,63 +873,6 @@
file_offset += section_table_file_size_;
}
-bool Elf::VerifySegmentOrder() {
- // We can only verify the segment order after FinalizeProgramTable(), since
- // we assume that all segments have been added, including the two program
- // table segments.
- ASSERT(program_table_file_size_ > 0);
-
- // Find the names and symbols for the .bss and .text segments.
- auto const bss_section_name = shstrtab_->Lookup(".bss");
- // For separate debugging information for assembly snapshots, no .bss section
- // is added. However, we're only interested in strict segment orders when
- // generating ELF snapshots, so only continue when there's a .bss section.
- if (bss_section_name == -1) return true;
- auto const text_section_name = shstrtab_->Lookup(".text");
- ASSERT(text_section_name != -1);
-
- auto const bss_symbol_name = dynstrtab_->Lookup("_kDartBSSData");
- auto const vm_symbol_name =
- dynstrtab_->Lookup(kVmSnapshotInstructionsAsmSymbol);
- auto const isolate_symbol_name =
- dynstrtab_->Lookup(kIsolateSnapshotInstructionsAsmSymbol);
- ASSERT(bss_symbol_name != -1);
- ASSERT(vm_symbol_name != -1);
- ASSERT(isolate_symbol_name != -1);
-
- auto const bss_symbol = dynsym_->FindSymbolWithNameIndex(bss_symbol_name);
- auto const vm_symbol = dynsym_->FindSymbolWithNameIndex(vm_symbol_name);
- auto const isolate_symbol =
- dynsym_->FindSymbolWithNameIndex(isolate_symbol_name);
- ASSERT(bss_symbol != nullptr);
- ASSERT(vm_symbol != nullptr);
- ASSERT(isolate_symbol != nullptr);
-
- // Check that the first non-program table segments are in the expected order.
- auto const bss_segment = segments_[2];
- ASSERT_EQUAL(bss_segment->segment_type, elf::PT_LOAD);
- ASSERT_EQUAL(bss_segment->section_name(), bss_section_name);
- ASSERT_EQUAL(bss_segment->memory_offset(), bss_symbol->offset);
- ASSERT_EQUAL(bss_segment->MemorySize(), bss_symbol->size);
- auto const vm_segment = segments_[3];
- ASSERT_EQUAL(vm_segment->segment_type, elf::PT_LOAD);
- ASSERT_EQUAL(vm_segment->section_name(), text_section_name);
- ASSERT_EQUAL(vm_segment->memory_offset(), vm_symbol->offset);
- ASSERT_EQUAL(vm_segment->MemorySize(), vm_symbol->size);
- auto const isolate_segment = segments_[4];
- ASSERT_EQUAL(isolate_segment->segment_type, elf::PT_LOAD);
- ASSERT_EQUAL(isolate_segment->section_name(), text_section_name);
- ASSERT_EQUAL(isolate_segment->memory_offset(), isolate_symbol->offset);
- ASSERT_EQUAL(isolate_segment->MemorySize(), isolate_symbol->size);
-
- // Also make sure that the memory offset of the VM segment is as expected.
- ASSERT_EQUAL(bss_segment->memory_offset(), kPageSize);
- ASSERT(bss_segment->MemorySize() <= kPageSize);
- ASSERT_EQUAL(vm_segment->memory_offset(), kVmSnapshotOffset);
-
- return true;
-}
-
void Elf::WriteHeader() {
#if defined(TARGET_ARCH_IS_32_BIT)
uint8_t size = elf::ELFCLASS32;
diff --git a/runtime/vm/elf.h b/runtime/vm/elf.h
index c204457..17ce455 100644
--- a/runtime/vm/elf.h
+++ b/runtime/vm/elf.h
@@ -26,12 +26,6 @@
static const intptr_t kPageSize = 4096;
- // Used by the non-symbolic stack frame printer to calculate the relocated
- // base address of the loaded ELF snapshot given the start of the VM
- // instructions. Only works for ELF snapshots written by Dart, not those
- // compiled from assembly.
- static uword SnapshotRelocatedBaseAddress(uword vm_start);
-
intptr_t NextMemoryOffset() const { return memory_offset_; }
intptr_t NextSectionIndex() const { return sections_.length(); }
intptr_t AddText(const char* name, const uint8_t* bytes, intptr_t size);
@@ -92,7 +86,6 @@
void FinalizeProgramTable();
void ComputeFileOffsets();
- bool VerifySegmentOrder();
void WriteHeader();
void WriteSectionTable();
diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc
index 3334ea1..5c13efe 100644
--- a/runtime/vm/guard_field_test.cc
+++ b/runtime/vm/guard_field_test.cc
@@ -32,7 +32,7 @@
"class A {\n"
" var f1 = 3.0;\n"
" dynamic f2 = 3;\n"
- " var f3 = new List(4);\n"
+ " var f3 = List<dynamic>.filled(4, null);\n"
" foo() {\n"
" f1 = f1 + f1;\n"
" }\n"
@@ -43,14 +43,14 @@
"}\n"
"\n"
"runFoo() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.foo();\n"
" }\n"
"}\n"
"\n"
"runBar() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.bar();\n"
" }\n"
@@ -83,7 +83,7 @@
"class A {\n"
" var f1 = 3.0;\n"
" dynamic f2 = 3;\n"
- " final f3 = new List(4);\n"
+ " final f3 = List<dynamic>.filled(4, null);\n"
" foo() {\n"
" f1 = f1 + f1;\n"
" }\n"
@@ -94,14 +94,14 @@
"}\n"
"\n"
"runFoo() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.foo();\n"
" }\n"
"}\n"
"\n"
"runBar() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.bar();\n"
" }\n"
@@ -136,7 +136,7 @@
"class A {\n"
" var f1 = 3.0;\n"
" dynamic f2 = 3;\n"
- " final f3 = new List();\n"
+ " final f3 = List.empty(growable: true);\n"
" foo() {\n"
" f1 = f1 + f1;\n"
" }\n"
@@ -147,14 +147,14 @@
"}\n"
"\n"
"runFoo() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.foo();\n"
" }\n"
"}\n"
"\n"
"runBar() {\n"
- " var a = new A();\n"
+ " var a = A();\n"
" for (int i = 0; i < 2000; i++) {\n"
" a.bar();\n"
" }\n"
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index 33c8500..461513d 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -68,7 +68,7 @@
TEST_CASE(LargeSweep) {
const char* kScriptChars =
"main() {\n"
- " return new List(8 * 1024 * 1024);\n"
+ " return List.filled(8 * 1024 * 1024, null);\n"
"}\n";
NOT_IN_PRODUCT(FLAG_verbose_gc = true);
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 0b0b911..63a49e6 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -310,11 +310,17 @@
auto& owner = Object::Handle(zone);
auto& url = String::Handle(zone);
auto& name = String::Handle(zone);
+ intptr_t trampolines_total_size = 0;
JSONWriter js;
js.OpenArray();
for (intptr_t i = 0; i < instructions_.length(); i++) {
auto& data = instructions_[i];
+ const bool is_trampoline = data.code_ == nullptr;
+ if (is_trampoline) {
+ trampolines_total_size += data.trampoline_length;
+ continue;
+ }
owner = WeakSerializationReference::Unwrap(data.code_->owner());
js.OpenObject();
if (owner.IsFunction()) {
@@ -337,6 +343,12 @@
js.PrintProperty("s", SizeInSnapshot(data.insns_->raw()));
js.CloseObject();
}
+ if (trampolines_total_size != 0) {
+ js.OpenObject();
+ js.PrintProperty("n", "[Stub] Trampoline");
+ js.PrintProperty("s", trampolines_total_size);
+ js.CloseObject();
+ }
js.CloseArray();
auto file_open = Dart::file_open_callback();
@@ -409,6 +421,9 @@
}
void ImageWriter::WriteROData(WriteStream* stream) {
+#if defined(DART_PRECOMPILER)
+ const intptr_t start_position = stream->Position();
+#endif
stream->Align(kMaxObjectAlignment);
// Heap page starts here.
@@ -419,6 +434,14 @@
// Zero values for other image header fields.
stream->Align(kMaxObjectAlignment);
ASSERT(stream->Position() - section_start == Image::kHeaderSize);
+#if defined(DART_PRECOMPILER)
+ if (profile_writer_ != nullptr) {
+ const intptr_t end_position = stream->Position();
+ profile_writer_->AttributeBytesTo(
+ V8SnapshotProfileWriter::ArtificialRootId(),
+ end_position - start_position);
+ }
+#endif
// Heap page objects start here.
@@ -661,6 +684,13 @@
text_offset += Align(kMaxObjectAlignment, text_offset);
ASSERT_EQUAL(text_offset, Image::kHeaderSize);
+#if defined(DART_PRECOMPILER)
+ if (profile_writer_ != nullptr) {
+ profile_writer_->AttributeBytesTo(
+ V8SnapshotProfileWriter::ArtificialRootId(),
+ (next_text_offset_ - image_size) + Image::kHeaderSize);
+ }
+#endif
// Only valid if bare_instruction_payloads is true.
V8SnapshotProfileWriter::ObjectId instructions_section_id(offset_space_, -1);
@@ -906,10 +936,10 @@
Align(Image::kBssAlignment);
assembly_stream_.Print("%s:\n", bss_symbol);
- // Currently we only put one symbol in the data section, the address of
- // DLRT_GetThreadForNativeCallback, which is populated when the snapshot is
- // loaded.
- WriteWordLiteralText(0);
+ auto const entry_count = vm ? BSS::kVmEntryCount : BSS::kIsolateEntryCount;
+ for (intptr_t i = 0; i < entry_count; i++) {
+ WriteWordLiteralText(0);
+ }
#endif
#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) || \
@@ -1095,15 +1125,24 @@
instructions_blob_stream_.WriteTargetWord(image_size);
#if defined(DART_PRECOMPILER)
// Store the offset of the BSS section from the instructions section here.
- // The lowest bit is set to indicate we compiled directly to ELF.
- const word bss_offset = bss_base_ - segment_base;
+ // If not compiling to ELF (and thus no BSS segment), write 0.
+ const word bss_offset = elf_ != nullptr ? bss_base_ - segment_base : 0;
ASSERT_EQUAL(Utils::RoundDown(bss_offset, Image::kBssAlignment), bss_offset);
- instructions_blob_stream_.WriteTargetWord(bss_offset | 0x1);
+ // Set the lowest bit if we are compiling to ELF.
+ const word compiled_to_elf = elf_ != nullptr ? 0x1 : 0x0;
+ instructions_blob_stream_.WriteTargetWord(bss_offset | compiled_to_elf);
#else
instructions_blob_stream_.WriteTargetWord(0); // No relocations.
#endif
instructions_blob_stream_.Align(kMaxObjectAlignment);
ASSERT_EQUAL(instructions_blob_stream_.Position(), Image::kHeaderSize);
+#if defined(DART_PRECOMPILER)
+ if (profile_writer_ != nullptr) {
+ profile_writer_->AttributeBytesTo(
+ V8SnapshotProfileWriter::ArtificialRootId(),
+ (image_size - next_text_offset_) + Image::kHeaderSize);
+ }
+#endif
// Only valid when bare_instructions_payloads is true.
const V8SnapshotProfileWriter::ObjectId instructions_section_id(
@@ -1277,12 +1316,12 @@
insns.PayloadStart() + reloc_offset);
// Overwrite the relocation position in the instruction stream with the
- // (positive) offset of the start of the payload from the start of the
- // BSS segment plus the addend in the relocation.
- instructions_blob_stream_.SetPosition(payload_offset + reloc_offset);
+ // offset of the BSS segment from the relocation position plus the
+ // addend in the relocation.
+ auto const text_offset = payload_offset + reloc_offset;
+ instructions_blob_stream_.SetPosition(text_offset);
- const compiler::target::word offset =
- bss_base_ - (segment_base + payload_offset + reloc_offset) + addend;
+ const compiler::target::word offset = bss_offset - text_offset + addend;
instructions_blob_stream_.WriteTargetWord(offset);
}
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 72411fb..da66a90 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -274,36 +274,44 @@
}
TEST_CASE(IsolateReload_KernelIncrementalCompileBaseClass) {
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
// clang-format off
- Dart_SourceFile sourcefiles[] = {
+ auto kSourceFile1 =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class State<T, U> {\n"
+ " T%s t;\n"
+ " U%s u;\n"
+ " State(List l) {\n"
+ " t = l[0] is T ? l[0] : null;\n"
+ " u = l[1] is U ? l[1] : null;\n"
+ " }\n"
+ "}\n",
+ nullableTag, nullableTag),
+ std::free);
+ Dart_SourceFile sourcefiles[3] = {
{
"file:///test-app.dart",
"import 'test-util.dart';\n"
"main() {\n"
" var v = doWork();"
- " return v == 42 ? 1: v == null ? -1: 0;\n"
+ " return v == 42 ? 1 : v == null ? -1 : 0;\n"
"}\n",
},
{
"file:///test-lib.dart",
- "class State<T, U> {\n"
- " T t;\n"
- " U u;\n"
- " State(List l) {\n"
- " t = l[0] is T? l[0]: null;\n"
- " u = l[1] is U? l[1]: null;\n"
- " }\n"
- "}\n",
+ kSourceFile1.get()
},
{
- "file:///test-util.dart",
- "import 'test-lib.dart';\n"
- "class MyAccountState extends State<int, String> {\n"
- " MyAccountState(List l): super(l) {}\n"
- " first() => t;\n"
- "}\n"
- "doWork() => new MyAccountState(<dynamic>[42, 'abc']).first();\n"
- }};
+ "file:///test-util.dart",
+ "import 'test-lib.dart';\n"
+ "class MyAccountState extends State<int, String> {\n"
+ " MyAccountState(List l): super(l) {}\n"
+ " first() => t;\n"
+ "}\n"
+ "doWork() => new MyAccountState(<dynamic>[42, 'abc']).first();\n"
+ }
+ };
// clang-format on
Dart_Handle lib = TestCase::LoadTestScriptWithDFE(
@@ -316,20 +324,22 @@
EXPECT_VALID(result);
EXPECT_EQ(1, value);
- // clang-format off
- Dart_SourceFile updated_sourcefiles[] = {
- {
- "file:///test-lib.dart",
- "class State<U, T> {\n"
- " T t;\n"
- " U u;\n"
- " State(List l) {\n"
- " t = l[0] is T? l[0]: null;\n"
- " u = l[1] is U? l[1]: null;\n"
- " }\n"
- "}\n",
- }};
- // clang-format on
+ auto kUpdatedSourceFile =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class State<U, T> {\n"
+ " T%s t;\n"
+ " U%s u;\n"
+ " State(List l) {\n"
+ " t = l[0] is T ? l[0] : null;\n"
+ " u = l[1] is U ? l[1] : null;\n"
+ " }\n"
+ "}\n",
+ nullableTag, nullableTag),
+ std::free);
+ Dart_SourceFile updated_sourcefiles[1] = {{
+ "file:///test-lib.dart",
+ kUpdatedSourceFile.get(),
+ }};
{
const uint8_t* kernel_buffer = NULL;
intptr_t kernel_buffer_size = 0;
@@ -717,34 +727,46 @@
}
TEST_CASE(IsolateReload_ConstructorChanged) {
- const char* kScript =
- "class A {\n"
- " int field;\n"
- " A() { field = 20; }\n"
- "}\n"
- "var savedA = new A();\n"
- "main() {\n"
- " var newA = new A();\n"
- " return 'saved:${savedA.field} new:${newA.field}';\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class A {\n"
+ " %s int field;\n"
+ " A() { field = 20; }\n"
+ "}\n"
+ "var savedA = A();\n"
+ "main() {\n"
+ " var newA = A();\n"
+ " return 'saved:${savedA.field} new:${newA.field}';\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("saved:20 new:20", SimpleInvokeStr(lib, "main"));
- const char* kReloadScript =
- "var _unused;"
- "class A {\n"
- " int field;\n"
- " A() { field = 10; }\n"
- "}\n"
- "var savedA = new A();\n"
- "main() {\n"
- " var newA = new A();\n"
- " return 'saved:${savedA.field} new:${newA.field}';\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "var _unused;"
+ "class A {\n"
+ " %s int field;\n"
+ " A() { field = 10; }\n"
+ "}\n"
+ "var savedA = A();\n"
+ "main() {\n"
+ " var newA = A();\n"
+ " return 'saved:${savedA.field} new:${newA.field}';\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ("saved:20 new:10", SimpleInvokeStr(lib, "main"));
}
@@ -1823,10 +1845,10 @@
"class C {\n"
" foo() => 'old';\n"
"}\n"
- "List list = new List(2);\n"
- "Set set = new Set();\n"
+ "List list = List<dynamic>.filled(2, null);\n"
+ "Set set = Set();\n"
"main() {\n"
- " var c = new C();\n"
+ " var c = C();\n"
" list[0] = c.foo;\n"
" list[1] = c.foo;\n"
" set.add(c.foo);\n"
@@ -1851,10 +1873,10 @@
"class C {\n"
" foo() => 'new';\n"
"}\n"
- "List list = new List(2);\n"
- "Set set = new Set();\n"
+ "List list = List<dynamic>.filled(2, null);\n"
+ "Set set = Set();\n"
"main() {\n"
- " var c = new C();\n"
+ " var c = C();\n"
" list[0] = c.foo;\n"
" list[1] = c.foo;\n"
" set.add(c.foo);\n"
@@ -3423,120 +3445,161 @@
}
TEST_CASE(IsolateReload_RunNewFieldInitializers) {
- const char* kScript =
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y.
- const char* kReloadScript =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = 7;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return value.y;\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = 7;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return value.y;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances.
EXPECT_EQ(7, SimpleInvoke(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersReferenceStaticField) {
- const char* kScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y.
- const char* kReloadScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- " int y = myInitialValue;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return value.y;\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return value.y;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances.
EXPECT_EQ(56, SimpleInvoke(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersLazy) {
- const char* kScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "Foo value1;\n"
- "main() {\n"
- " value = new Foo();\n"
- " value1 = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "%s Foo value1;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " value1 = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag, lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y.
- const char* kReloadScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- " int y = myInitialValue++;\n"
- "}\n"
- "Foo value;\n"
- "Foo value1;\n"
- "main() {\n"
- " return '${myInitialValue} ${value.y} ${value1.y} ${myInitialValue}';\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue++;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "%s Foo value1;\n"
+ "main() {\n"
+ " return '${myInitialValue} ${value.y} ${value1.y} "
+ "${myInitialValue}';\n"
+ "}\n",
+ lateTag, lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that field initializers ran lazily.
EXPECT_STREQ("56 56 57 58", SimpleInvokeStr(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersLazyConst) {
- const char* kScript =
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
@@ -3544,158 +3607,204 @@
// function in the VM because the initializer is a literal, but we should not
// eagerly initialize with the literal so that the behavior doesn't depend on
// this optimization.
- const char* kReloadScript =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = 5;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return 0;\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = 5;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return 0;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_EQ(0, SimpleInvoke(lib, "main"));
// Change y's initializer and check this new initializer is used.
- const char* kReloadScript2 =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = 6;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return value.y;\n"
- "}\n";
+ auto kReloadScript2 =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = 6;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return value.y;\n"
+ "}\n",
+ lateTag),
+ std::free);
- lib = TestCase::ReloadTestScript(kReloadScript2);
+ lib = TestCase::ReloadTestScript(kReloadScript2.get());
EXPECT_VALID(lib);
EXPECT_EQ(6, SimpleInvoke(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersLazyTransitive) {
- const char* kScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "Foo value1;\n"
- "main() {\n"
- " value = new Foo();\n"
- " value1 = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "%s Foo value1;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " value1 = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag, lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y. Do not touch y.
- const char* kReloadScript =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- " int y = myInitialValue++;\n"
- "}\n"
- "Foo value;\n"
- "Foo value1;\n"
- "main() {\n"
- " return '${myInitialValue}';\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue++;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "%s Foo value1;\n"
+ "main() {\n"
+ " return '${myInitialValue}';\n"
+ "}\n",
+ lateTag, lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ("56", SimpleInvokeStr(lib, "main"));
// Reload again. Field y's getter still needs to keep for initialization even
// though it is no longer new.
- const char* kReloadScript2 =
- "int myInitialValue = 8 * 7;\n"
- "class Foo {\n"
- " int x = 4;\n"
- " int y = myInitialValue++;\n"
- "}\n"
- "Foo value;\n"
- "Foo value1;\n"
- "main() {\n"
- " return '${myInitialValue} ${value.y} ${value1.y} ${myInitialValue}';\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript2 = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue++;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "%s Foo value1;\n"
+ "main() {\n"
+ " return '${myInitialValue} ${value.y} ${value1.y} "
+ "${myInitialValue}';\n"
+ "}\n",
+ lateTag, lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript2);
+ lib = TestCase::ReloadTestScript(kReloadScript2.get());
EXPECT_VALID(lib);
// Verify that field initializers ran lazily.
EXPECT_STREQ("56 56 57 58", SimpleInvokeStr(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersThrows) {
- const char* kScript =
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y.
- const char* kReloadScript =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = throw 'exception';\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " try {\n"
- " return value.y.toString();\n"
- " } catch (e) {\n"
- " return e.toString();\n"
- " }\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = throw 'exception';\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " try {\n"
+ " return value.y.toString();\n"
+ " } catch (e) {\n"
+ " return e.toString();\n"
+ " }\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances.
EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
}
TEST_CASE(IsolateReload_RunNewFieldInitializersCyclicInitialization) {
- const char* kScript =
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y.
- const char* kReloadScript =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = value.y;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " try {\n"
- " return value.y.toString();\n"
- " } catch (e) {\n"
- " return e.toString();\n"
- " }\n"
- "}\n";
-
- lib = TestCase::ReloadTestScript(kReloadScript);
+ // clang-format off
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = value.y;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " try {\n"
+ " return value.y.toString();\n"
+ " } catch (e) {\n"
+ " return e.toString();\n"
+ " }\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ("Stack Overflow", SimpleInvokeStr(lib, "main"));
}
@@ -3703,143 +3812,190 @@
// When an initializer expression has a syntax error, we detect it at reload
// time.
TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError) {
- const char* kScript =
- "class Foo {\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y with a syntax error in the initializing expression.
- const char* kReloadScript =
- "class Foo {\n"
- " int x = 4;\n"
- " int y = ......;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return '${value.y == null}';"
- "}\n";
+ // clang-format off
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = ......;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
// The reload fails because the initializing expression is parsed at
// class finalization time.
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_ERROR(lib, "...");
}
// When an initializer expression has a syntax error, we detect it at reload
// time.
TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError2) {
- const char* kScript =
- "class Foo {\n"
- " Foo() { /* default constructor */ }\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y with a syntax error in the initializing expression.
- const char* kReloadScript =
- "class Foo {\n"
- " Foo() { /* default constructor */ }\n"
- " int x = 4;\n"
- " int y = ......;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return '${value.y == null}';"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ " int y = ......;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
// The reload fails because the initializing expression is parsed at
// class finalization time.
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_ERROR(lib, "...");
}
// When an initializer expression has a syntax error, we detect it at reload
// time.
TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError3) {
- const char* kScript =
- "class Foo {\n"
- " Foo() { /* default constructor */ }\n"
- " int x = 4;\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " return value.x;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " return value.x;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(4, SimpleInvoke(lib, "main"));
// Add the field y with a syntax error in the initializing expression.
- const char* kReloadScript =
- "class Foo {\n"
- " Foo() { /* default constructor */ }\n"
- " int x = 4;\n"
- " int y = ......\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return '${value.y == null}';"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ " int y = ......\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
// The reload fails because the initializing expression is parsed at
// class finalization time.
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_ERROR(lib, "......");
}
TEST_CASE(IsolateReload_RunNewFieldInitializersSuperClass) {
- const char* kScript =
- "class Super {\n"
- " static var foo = 'right';\n"
- "}\n"
- "class Foo extends Super {\n"
- " static var foo = 'wrong';\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " Super.foo;\n"
- " Foo.foo;\n"
- " value = new Foo();\n"
- " return 0;\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Super {\n"
+ " static var foo = 'right';\n"
+ "}\n"
+ "class Foo extends Super {\n"
+ " static var foo = 'wrong';\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " Super.foo;\n"
+ " Foo.foo;\n"
+ " value = Foo();\n"
+ " return 0;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_EQ(0, SimpleInvoke(lib, "main"));
- const char* kReloadScript =
- "class Super {\n"
- " static var foo = 'right';\n"
- " var newField = foo;\n"
- "}\n"
- "class Foo extends Super {\n"
- " static var foo = 'wrong';\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return value.newField;\n"
- "}\n";
+ // clang-format on
+ auto kReloadScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Super {\n"
+ " static var foo = 'right';\n"
+ " var newField = foo;\n"
+ "}\n"
+ "class Foo extends Super {\n"
+ " static var foo = 'wrong';\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return value.newField;\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format off
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances in the
// correct scope.
@@ -3851,50 +4007,62 @@
}
TEST_CASE(IsolateReload_RunNewFieldInitializersWithConsts) {
- const char* kScript =
- "class C {\n"
- " final x;\n"
- " const C(this.x);\n"
- "}\n"
- "var a = const C(const C(1));\n"
- "var b = const C(const C(2));\n"
- "var c = const C(const C(3));\n"
- "var d = const C(const C(4));\n"
- "class Foo {\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " value = new Foo();\n"
- " a; b; c; d;\n"
- " return 'Okay';\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class C {\n"
+ " final x;\n"
+ " const C(this.x);\n"
+ "}\n"
+ "var a = const C(const C(1));\n"
+ "var b = const C(const C(2));\n"
+ "var c = const C(const C(3));\n"
+ "var d = const C(const C(4));\n"
+ "class Foo {\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " value = Foo();\n"
+ " a; b; c; d;\n"
+ " return 'Okay';\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), nullptr);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
- const char* kReloadScript =
- "class C {\n"
- " final x;\n"
- " const C(this.x);\n"
- "}\n"
- "var a = const C(const C(1));\n"
- "var b = const C(const C(2));\n"
- "var c = const C(const C(3));\n"
- "var d = const C(const C(4));\n"
- "class Foo {\n"
- " var d = const C(const C(4));\n"
- " var c = const C(const C(3));\n"
- " var b = const C(const C(2));\n"
- " var a = const C(const C(1));\n"
- "}\n"
- "Foo value;\n"
- "main() {\n"
- " return '${identical(a, value.a)} ${identical(b, value.b)}'"
- " ' ${identical(c, value.c)} ${identical(d, value.d)}';\n"
- "}\n";
-
- lib = TestCase::ReloadTestScript(kReloadScript);
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(
+ nullptr,
+ "class C {\n"
+ " final x;\n"
+ " const C(this.x);\n"
+ "}\n"
+ "var a = const C(const C(1));\n"
+ "var b = const C(const C(2));\n"
+ "var c = const C(const C(3));\n"
+ "var d = const C(const C(4));\n"
+ "class Foo {\n"
+ " var d = const C(const C(4));\n"
+ " var c = const C(const C(3));\n"
+ " var b = const C(const C(2));\n"
+ " var a = const C(const C(1));\n"
+ "}\n"
+ "%s Foo value;\n"
+ "main() {\n"
+ " return '${identical(a, value.a)} ${identical(b, value.b)}'"
+ " ' ${identical(c, value.c)} ${identical(d, value.d)}';\n"
+ "}\n",
+ lateTag),
+ std::free);
+ // clang-format on
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances and the const
// expressions were properly canonicalized.
@@ -3902,36 +4070,49 @@
}
TEST_CASE(IsolateReload_RunNewFieldInitializersWithGenerics) {
- const char* kScript =
- "class Foo<T> {\n"
- " T x;\n"
- "}\n"
- "Foo value1;\n"
- "Foo value2;\n"
- "main() {\n"
- " value1 = new Foo<String>();\n"
- " value2 = new Foo<int>();\n"
- " return 'Okay';\n"
- "}\n";
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = null_safety ? "?" : "";
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "class Foo<T> {\n"
+ " T%s x;\n"
+ "}\n"
+ "%s Foo value1;\n"
+ "%s Foo value2;\n"
+ "main() {\n"
+ " value1 = Foo<String>();\n"
+ " value2 = Foo<int>();\n"
+ " return 'Okay';\n"
+ "}\n",
+ nullableTag, lateTag, lateTag),
+ std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
- const char* kReloadScript =
- "class Foo<T> {\n"
- " T x;\n"
- " List<T> y = new List<T>();"
- " dynamic z = <T,T>{};"
- "}\n"
- "Foo value1;\n"
- "Foo value2;\n"
- "main() {\n"
- " return '${value1.y.runtimeType} ${value1.z.runtimeType}'"
- " ' ${value2.y.runtimeType} ${value2.z.runtimeType}';\n"
- "}\n";
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(
+ OS::SCreate(nullptr,
+ "class Foo<T> {\n"
+ " T%s x;\n"
+ " List<T> y = List<T>.empty();"
+ " dynamic z = <T,T>{};"
+ "}\n"
+ "%s Foo value1;\n"
+ "%s Foo value2;\n"
+ "main() {\n"
+ " return '${value1.y.runtimeType} ${value1.z.runtimeType}'"
+ " ' ${value2.y.runtimeType} ${value2.z.runtimeType}';\n"
+ "}\n",
+ nullableTag, lateTag, lateTag),
+ std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
// Verify that we ran field initializers on existing instances and
// correct type arguments were used.
@@ -4066,26 +4247,33 @@
}
TEST_CASE(IsolateReload_ExistingFieldChangesType) {
- const char* kScript = R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ R"(
class Foo {
int x = 42;
}
- Foo value;
+ %s Foo value;
main() {
- value = new Foo();
+ value = Foo();
return 'Okay';
}
- )";
+ )",
+ lateTag), std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
- const char* kReloadScript = R"(
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class Foo {
double x = 42.0;
}
- Foo value;
+ %s Foo value;
main() {
try {
return value.x.toString();
@@ -4093,9 +4281,11 @@
return e.toString();
}
}
- )";
+ )",
+ lateTag), std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ(
"type 'int' is not a subtype of type 'double' of 'function result'",
@@ -4135,33 +4325,38 @@
}
TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirect) {
- const char* kScript = R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B extends A {}
class Foo {
A x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
- value = new Foo(new B());
+ value = Foo(B());
return 'Okay';
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
// B is no longer a subtype of A.
- const char* kReloadScript = R"(
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B {}
class Foo {
A x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
try {
return value.x.toString();
@@ -4169,9 +4364,10 @@
return e.toString();
}
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ("type 'B' is not a subtype of type 'A' of 'function result'",
SimpleInvokeStr(lib, "main"));
@@ -4214,33 +4410,38 @@
}
TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectGeneric) {
- const char* kScript = R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B extends A {}
class Foo {
List<A> x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
- value = new Foo(new List<B>());
+ value = Foo(List<B>.empty());
return 'Okay';
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
// B is no longer a subtype of A.
- const char* kReloadScript = R"(
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B {}
class Foo {
List<A> x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
try {
return value.x.toString();
@@ -4248,9 +4449,10 @@
return e.toString();
}
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ(
"type 'List<B>' is not a subtype of type 'List<A>' of 'function result'",
@@ -4262,7 +4464,7 @@
class A {}
class B extends A {}
List<A> value = init();
- init() => new List<B>();
+ init() => List<B>.empty();
main() {
return value.toString();
}
@@ -4277,7 +4479,7 @@
class A {}
class B {}
List<A> value = init();
- init() => new List<A>();
+ init() => List<A>.empty();
main() {
try {
return value.toString();
@@ -4295,7 +4497,11 @@
}
TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectFunction) {
- const char* kScript = R"(
+ const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* lateTag = null_safety ? "late" : "";
+
+ // clang-format off
+ auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B extends A {}
typedef bool Predicate(B b);
@@ -4303,19 +4509,21 @@
Predicate x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
- value = new Foo((A a) => true);
+ value = Foo((A a) => true);
return 'Okay';
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL);
EXPECT_VALID(lib);
EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main"));
// B is no longer a subtype of A.
- const char* kReloadScript = R"(
+ // clang-format off
+ auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"(
class A {}
class B {}
typedef bool Predicate(B b);
@@ -4323,7 +4531,7 @@
Predicate x;
Foo(this.x);
}
- Foo value;
+ %s Foo value;
main() {
try {
return value.x.toString();
@@ -4331,9 +4539,10 @@
return e.toString();
}
}
- )";
+ )", lateTag), std::free);
+ // clang-format on
- lib = TestCase::ReloadTestScript(kReloadScript);
+ lib = TestCase::ReloadTestScript(kReloadScript.get());
EXPECT_VALID(lib);
EXPECT_STREQ(
"type '(A) => bool' is not a subtype of type '(B) => bool' of 'function "
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index d4dc8f3..10a09c9 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -28,11 +28,11 @@
// Ignores printed lines.
"var _nullPrintClosure = (String line) {};\n"
"void entry(message) {}\n"
- "int testMain() {\n"
+ "void testMain() {\n"
" Isolate.spawn(entry, null);\n"
// TODO(floitsch): the following code is only to bump the event loop
// so it executes asynchronous microtasks.
- " var rp = new RawReceivePort();\n"
+ " var rp = RawReceivePort();\n"
" rp.sendPort.send(null);\n"
" rp.handler = (_) { rp.close(); };\n"
"}\n";
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index e3e3b52..3a77645 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -137,7 +137,7 @@
while (reader->offset() > 0) {
intptr_t size = reader->ReadUInt32();
intptr_t start = reader->offset() - size;
- if (start < 0) {
+ if (start < 0 || size <= 0) {
if (error != nullptr) {
*error = kKernelInvalidSizeIndicated;
}
diff --git a/runtime/vm/native_symbol.h b/runtime/vm/native_symbol.h
index 84aad3c..9aa8ba4 100644
--- a/runtime/vm/native_symbol.h
+++ b/runtime/vm/native_symbol.h
@@ -17,7 +17,9 @@
static void Init();
static void Cleanup();
static char* LookupSymbolName(uword pc, uword* start);
- static bool LookupSharedObject(uword pc, uword* dso_base, char** dso_name);
+ static bool LookupSharedObject(uword pc,
+ uword* dso_base = nullptr,
+ char** dso_name = nullptr);
static void FreeSymbolName(char* name);
static void AddSymbols(const char* dso_name, void* buffer, size_t size);
};
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index d1f78aa..1e4781c 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -23621,28 +23621,31 @@
// Prints the best representation(s) for the call address.
static void PrintNonSymbolicStackFrameBody(ZoneTextBuffer* buffer,
uword call_addr,
- uword isolate_dso_base,
uword isolate_instructions,
- uword vm_instructions) {
+ uword vm_instructions,
+ uword isolate_relocated_address) {
const Image vm_image(reinterpret_cast<const void*>(vm_instructions));
const Image isolate_image(
reinterpret_cast<const void*>(isolate_instructions));
if (isolate_image.contains(call_addr)) {
- if (isolate_image.compiled_to_elf() && isolate_dso_base != 0) {
- buffer->Printf(" virt %" Pp "", call_addr - isolate_dso_base);
+ auto const symbol_name = kIsolateSnapshotInstructionsAsmSymbol;
+ auto const offset = call_addr - isolate_instructions;
+ // Only print the relocated address of the call when we know the saved
+ // debugging information (if any) will have the same relocated address.
+ if (isolate_image.compiled_to_elf()) {
+ buffer->Printf(" virt %" Pp "", isolate_relocated_address + offset);
}
- buffer->Printf(" %s+0x%" Px "", kIsolateSnapshotInstructionsAsmSymbol,
- call_addr - isolate_instructions);
+ buffer->Printf(" %s+0x%" Px "", symbol_name, offset);
} else if (vm_image.contains(call_addr)) {
+ auto const offset = call_addr - vm_instructions;
// We currently don't print 'virt' entries for vm addresses, even if
// they were compiled to ELF, as we should never encounter these in
// non-symbolic stack traces (since stub addresses are stripped).
//
// In case they leak due to code issues elsewhere, we still print them as
// <vm symbol>+<offset>, just to distinguish from other cases.
- buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol,
- call_addr - vm_instructions);
+ buffer->Printf(" %s+0x%" Px "", kVmSnapshotInstructionsAsmSymbol, offset);
} else {
// This case should never happen, since these are not addresses within the
// VM or app isolate instructions sections, so make it easy to notice.
@@ -23703,6 +23706,16 @@
PrintSymbolicStackFrameBody(buffer, function_name, url, line, column);
}
+// Find the relocated base of the given instructions section.
+uword InstructionsRelocatedAddress(uword instructions_start) {
+ Image image(reinterpret_cast<const uint8_t*>(instructions_start));
+ auto const bss_start =
+ reinterpret_cast<const uword*>(instructions_start + image.bss_offset());
+ auto const index =
+ BSS::RelocationIndex(BSS::Relocation::InstructionsRelocatedAddress);
+ return bss_start[index];
+}
+
const char* StackTrace::ToCString() const {
auto const T = Thread::Current();
auto const zone = T->zone();
@@ -23721,38 +23734,10 @@
T->isolate_group()->source()->snapshot_instructions);
auto const vm_instructions = reinterpret_cast<uword>(
Dart::vm_isolate()->group()->source()->snapshot_instructions);
- uword isolate_dso_base;
- if (!NativeSymbolResolver::LookupSharedObject(isolate_instructions,
- &isolate_dso_base, nullptr)) {
- // This isn't a natively loaded snapshot, so try to detect non-natively
- // loaded compiled-to-ELF snapshots.
- const Image vm_image(reinterpret_cast<const void*>(vm_instructions));
- const Image isolate_image(
- reinterpret_cast<const void*>(isolate_instructions));
-
- if (vm_image.compiled_to_elf() && isolate_image.compiled_to_elf()) {
- // If the VM and isolate were loaded from the same snapshot, then the
- // isolate instructions will immediately follow the VM instructions in
- // memory, and the VM section is always at a fixed offset from the DSO
- // base in snapshots we generate.
- const uword next_section_after_vm =
- Utils::RoundUp(reinterpret_cast<uword>(vm_image.object_start()) +
- vm_image.object_size(),
- Elf::kPageSize);
- if (isolate_instructions == next_section_after_vm) {
- isolate_dso_base = Elf::SnapshotRelocatedBaseAddress(vm_instructions);
- }
- // If not, then we have no way of reverse-engineering the DSO base for
- // the isolate without extending the embedder to return this information
- // or encoding it somehow in the instructions image like the BSS offset.
- //
- // For the latter, the Image header size must match the HeapPage header
- // size, and there's no remaining unused space in the Image header on
- // 64-bit architectures. Thus, we'd have to increase the header size of
- // both HeapPage and Image or create a special Object to put in the body
- // of the Image to store extended header information.
- }
- }
+ auto const vm_relocated_address =
+ InstructionsRelocatedAddress(vm_instructions);
+ auto const isolate_relocated_address =
+ InstructionsRelocatedAddress(isolate_instructions);
if (FLAG_dwarf_stack_traces_mode) {
// The Dart standard requires the output of StackTrace.toString to include
// all pending activations with precise source locations (i.e., to expand
@@ -23767,15 +23752,14 @@
OSThread* thread = OSThread::Current();
buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(),
OSThread::ThreadIdToIntPtr(thread->id()), thread->name());
+ // Print the dso_base of the VM and isolate_instructions. We print both here
+ // as the VM and isolate may be loaded from different snapshot images.
+ buffer.Printf("isolate_dso_base: %" Px "",
+ isolate_instructions - isolate_relocated_address);
+ buffer.Printf(", vm_dso_base: %" Px "\n",
+ vm_instructions - vm_relocated_address);
buffer.Printf("isolate_instructions: %" Px "", isolate_instructions);
- buffer.Printf(" vm_instructions: %" Px "", vm_instructions);
- // Print the dso_base of the isolate_instructions, since printed stack
- // traces won't include stub frames. If VM isolates ever start including
- // Dart code, adjust this appropriately.
- if (isolate_dso_base != 0) {
- buffer.Printf(" isolate_dso_base: %" Px "", isolate_dso_base);
- }
- buffer.Printf("\n");
+ buffer.Printf(", vm_instructions: %" Px "\n", vm_instructions);
}
#endif
@@ -23828,9 +23812,9 @@
// This output is formatted like Android's debuggerd. Note debuggerd
// prints call addresses instead of return addresses.
buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr);
- PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_dso_base,
- isolate_instructions,
- vm_instructions);
+ PrintNonSymbolicStackFrameBody(
+ &buffer, call_addr, isolate_instructions, vm_instructions,
+ isolate_relocated_address);
frame_index++;
continue;
} else if (function.IsNull()) {
@@ -23838,9 +23822,9 @@
// retained, so instead print the static symbol + offset like the
// non-symbolic stack traces.
PrintSymbolicStackFrameIndex(&buffer, frame_index);
- PrintNonSymbolicStackFrameBody(&buffer, call_addr, isolate_dso_base,
- isolate_instructions,
- vm_instructions);
+ PrintNonSymbolicStackFrameBody(
+ &buffer, call_addr, isolate_instructions, vm_instructions,
+ isolate_relocated_address);
frame_index++;
continue;
}
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 210d32c..d09eace 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1814,8 +1814,8 @@
char buffer[1024];
Utils::SNPrint(buffer, sizeof(buffer),
"main() {\n"
- " new List(%" Pd
- ");\n"
+ " List.filled(%" Pd
+ ", null);\n"
"}\n",
length);
Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
@@ -1843,8 +1843,8 @@
char buffer[1024];
Utils::SNPrint(buffer, sizeof(buffer),
"main() {\n"
- " return new List(%" Pd
- ");\n"
+ " return List.filled(%" Pd
+ ", null);\n"
"}\n",
kOneTooMany);
Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
@@ -1857,8 +1857,8 @@
char buffer[1024];
Utils::SNPrint(buffer, sizeof(buffer),
"main() {\n"
- " return new List(%" Pd
- ");\n"
+ " return List.filled(%" Pd
+ ", null);\n"
"}\n",
Array::kMaxElements);
Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
@@ -3748,39 +3748,45 @@
}
TEST_CASE(Metadata) {
- const char* kScriptChars =
- "@metafoo \n"
- "class Meta { \n"
- " final m; \n"
- " const Meta(this.m); \n"
- "} \n"
- " \n"
- "const metafoo = 'metafoo'; \n"
- "const metabar = 'meta' 'bar'; \n"
- " \n"
- "@metafoo \n"
- "@Meta(0) String gVar; \n"
- " \n"
- "@metafoo \n"
- "get tlGetter => gVar; \n"
- " \n"
- "@metabar \n"
- "class A { \n"
- " @metafoo \n"
- " @metabar \n"
- " @Meta('baz') \n"
- " var aField; \n"
- " \n"
- " @metabar @Meta('baa') \n"
- " int aFunc(a,b) => a + b; \n"
- "} \n"
- " \n"
- "@Meta('main') \n"
- "A main() { \n"
- " return new A(); \n"
- "} \n";
+ bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = nullSafety ? "?" : "";
+ // clang-format off
+ auto kScriptChars =
+ Utils::CStringUniquePtr(OS::SCreate(nullptr,
+ "@metafoo \n"
+ "class Meta { \n"
+ " final m; \n"
+ " const Meta(this.m); \n"
+ "} \n"
+ " \n"
+ "const metafoo = 'metafoo'; \n"
+ "const metabar = 'meta' 'bar'; \n"
+ " \n"
+ "@metafoo \n"
+ "@Meta(0) String%s gVar; \n"
+ " \n"
+ "@metafoo \n"
+ "get tlGetter => gVar; \n"
+ " \n"
+ "@metabar \n"
+ "class A { \n"
+ " @metafoo \n"
+ " @metabar \n"
+ " @Meta('baz') \n"
+ " var aField; \n"
+ " \n"
+ " @metabar @Meta('baa') \n"
+ " int aFunc(a,b) => a + b; \n"
+ "} \n"
+ " \n"
+ "@Meta('main') \n"
+ "A main() { \n"
+ " return A(); \n"
+ "} \n",
+ nullableTag), std::free);
+ // clang-format on
- Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars.get(), NULL);
EXPECT_VALID(h_lib);
Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
EXPECT_VALID(result);
@@ -4412,8 +4418,8 @@
const char* kScript =
"import 'dart:collection';\n"
"makeMap() {\n"
- " Function eq = (a, b) => true;\n"
- " Function hc = (a) => 42;\n"
+ " bool Function(dynamic, dynamic) eq = (a, b) => true;\n"
+ " int Function(dynamic) hc = (a) => 42;\n"
" return new LinkedHashMap(equals: eq, hashCode: hc);\n"
"}";
Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL);
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 62167d5..211367b 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -936,8 +936,8 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
const char* kScript =
- "List foo() => new List(4);\n"
- "List bar() => new List();\n";
+ "List foo() => List.filled(4, null);\n"
+ "List bar() => List.empty(growable: true);\n";
const Library& root_library = Library::Handle(LoadTestScript(kScript));
Isolate* isolate = thread->isolate();
@@ -2437,20 +2437,20 @@
ISOLATE_UNIT_TEST_CASE(Profiler_GetSourceReport) {
EnableProfiler();
const char* kScript =
- "doWork(i) => i * i;\n"
- "main() {\n"
- " var sum = 0;\n"
- " for (var i = 0; i < 100; i++) {\n"
+ "int doWork(i) => i * i;\n"
+ "int main() {\n"
+ " int sum = 0;\n"
+ " for (int i = 0; i < 100; i++) {\n"
" sum += doWork(i);\n"
" }\n"
" return sum;\n"
"}\n";
// Token position of * in `i * i`.
- const TokenPosition squarePosition = TokenPosition(15);
+ const TokenPosition squarePosition = TokenPosition(19);
// Token position of the call to `doWork`.
- const TokenPosition callPosition = TokenPosition(90);
+ const TokenPosition callPosition = TokenPosition(95);
DisableNativeProfileScope dnps;
// Disable profiling for this thread.
@@ -2542,14 +2542,14 @@
}
// Verify positions in do_work.
- EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",15]", js.ToCString());
+ EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",19]", js.ToCString());
// Verify exclusive ticks in do_work.
EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString());
// Verify inclusive ticks in do_work.
EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
// Verify positions in main.
- EXPECT_SUBSTRING("\"positions\":[90]", js.ToCString());
+ EXPECT_SUBSTRING("\"positions\":[95]", js.ToCString());
// Verify exclusive ticks in main.
EXPECT_SUBSTRING("\"exclusiveTicks\":[0]", js.ToCString());
// Verify inclusive ticks in main.
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 4be78c66..44a52c1 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -699,29 +699,37 @@
}
VM_UNIT_TEST_CASE(FullSnapshot) {
- const char* kScriptChars =
- "class Fields {\n"
- " Fields(int i, int j) : fld1 = i, fld2 = j {}\n"
- " int fld1;\n"
- " final int fld2;\n"
- " final int bigint_fld = 0xfffffffffff;\n"
- " static int fld3;\n"
- " static const int smi_sfld = 10;\n"
- " static const int bigint_sfld = 0xfffffffffff;\n"
- "}\n"
- "class Expect {\n"
- " static void equals(x, y) {\n"
- " if (x != y) throw new ArgumentError('not equal');\n"
- " }\n"
- "}\n"
- "class FieldsTest {\n"
- " static Fields testMain() {\n"
- " Expect.equals(true, Fields.bigint_sfld == 0xfffffffffff);\n"
- " Fields obj = new Fields(10, 20);\n"
- " Expect.equals(true, obj.bigint_fld == 0xfffffffffff);\n"
- " return obj;\n"
- " }\n"
- "}\n";
+ bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = nullSafety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(
+ nullptr,
+ "class Fields {\n"
+ " Fields(int i, int j) : fld1 = i, fld2 = j {}\n"
+ " int fld1;\n"
+ " final int fld2;\n"
+ " final int bigint_fld = 0xfffffffffff;\n"
+ " static int%s fld3;\n"
+ " static const int smi_sfld = 10;\n"
+ " static const int bigint_sfld = 0xfffffffffff;\n"
+ "}\n"
+ "class Expect {\n"
+ " static void equals(x, y) {\n"
+ " if (x != y) throw new ArgumentError('not equal');\n"
+ " }\n"
+ "}\n"
+ "class FieldsTest {\n"
+ " static Fields testMain() {\n"
+ " Expect.equals(true, Fields.bigint_sfld == 0xfffffffffff);\n"
+ " Fields obj = new Fields(10, 20);\n"
+ " Expect.equals(true, obj.bigint_fld == 0xfffffffffff);\n"
+ " return obj;\n"
+ " }\n"
+ "}\n",
+ nullableTag),
+ std::free);
+ // clang-format on
Dart_Handle result;
uint8_t* isolate_snapshot_data_buffer;
@@ -733,7 +741,7 @@
TestIsolateScope __test_isolate__;
// Create a test library and Load up a test script in it.
- TestCase::LoadTestScript(kScriptChars, NULL);
+ TestCase::LoadTestScript(kScriptChars.get(), NULL);
Thread* thread = Thread::Current();
TransitionNativeToVM transition(thread);
@@ -848,19 +856,19 @@
" return \"\\u{10000}\\u{1F601}\\u{1F637}\\u{20000}\";\n"
"}\n"
"getLeadSurrogateString() {\n"
- " return new String.fromCharCodes([0xd800]);\n"
+ " return String.fromCharCodes([0xd800]);\n"
"}\n"
"getTrailSurrogateString() {\n"
" return \"\\u{10000}\".substring(1);\n"
"}\n"
"getSurrogatesString() {\n"
- " return new String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n"
+ " return String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n"
"}\n"
"getCrappyString() {\n"
- " return new String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n"
+ " return String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n"
"}\n"
"getList() {\n"
- " return new List(kArrayLength);\n"
+ " return List.filled(kArrayLength, null);\n"
"}\n";
TestCase::CreateTestIsolate();
@@ -959,20 +967,20 @@
static const char* kScriptChars =
"final int kArrayLength = 10;\n"
"getList() {\n"
- " return new List(kArrayLength);\n"
+ " return List.filled(kArrayLength, null);\n"
"}\n"
"getIntList() {\n"
- " var list = new List<int>(kArrayLength);\n"
+ " var list = List<int>.filled(kArrayLength, 0);\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = i;\n"
" return list;\n"
"}\n"
"getStringList() {\n"
- " var list = new List<String>(kArrayLength);\n"
+ " var list = List<String>.filled(kArrayLength, '');\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = i.toString();\n"
" return list;\n"
"}\n"
"getMixedList() {\n"
- " var list = new List(kArrayLength);\n"
+ " var list = List<dynamic>.filled(kArrayLength, null);\n"
" list[0] = 0;\n"
" list[1] = '1';\n"
" list[2] = 2.2;\n"
@@ -1291,46 +1299,46 @@
"final int kArrayLength = 10;\n"
"getStringList() {\n"
" var s = 'Hello, world!';\n"
- " var list = new List<String>(kArrayLength);\n"
+ " var list = List<String>.filled(kArrayLength, '');\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = s;\n"
" return list;\n"
"}\n"
"getMintList() {\n"
" var mint = 0x7FFFFFFFFFFFFFFF;\n"
- " var list = new List(kArrayLength);\n"
+ " var list = List.filled(kArrayLength, 0);\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = mint;\n"
" return list;\n"
"}\n"
"getDoubleList() {\n"
" var d = 3.14;\n"
- " var list = new List<double>(kArrayLength);\n"
+ " var list = List<double>.filled(kArrayLength, 0.0);\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = d;\n"
" return list;\n"
"}\n"
"getTypedDataList() {\n"
- " var byte_array = new Uint8List(256);\n"
- " var list = new List(kArrayLength);\n"
+ " var byte_array = Uint8List(256);\n"
+ " var list = List<dynamic>.filled(kArrayLength, null);\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = byte_array;\n"
" return list;\n"
"}\n"
"getTypedDataViewList() {\n"
- " var uint8_list = new Uint8List(256);\n"
+ " var uint8_list = Uint8List(256);\n"
" uint8_list[64] = 1;\n"
" var uint8_list_view =\n"
- " new Uint8List.view(uint8_list.buffer, 64, 128);\n"
- " var list = new List(kArrayLength);\n"
+ " Uint8List.view(uint8_list.buffer, 64, 128);\n"
+ " var list = List<dynamic>.filled(kArrayLength, null);\n"
" for (var i = 0; i < kArrayLength; i++) list[i] = uint8_list_view;\n"
" return list;\n"
"}\n"
"getMixedList() {\n"
- " var list = new List(kArrayLength);\n"
+ " var list = List<dynamic>.filled(kArrayLength, null);\n"
" for (var i = 0; i < kArrayLength; i++) {\n"
" list[i] = ((i % 2) == 0) ? 'A' : 2.72;\n"
" }\n"
" return list;\n"
"}\n"
"getSelfRefList() {\n"
- " var list = new List(kArrayLength);\n"
+ " var list = List<dynamic>.filled(kArrayLength, null, growable: true);\n"
" for (var i = 0; i < kArrayLength; i++) {\n"
" list[i] = list;\n"
" }\n"
@@ -1697,71 +1705,71 @@
static const char* kScriptChars =
"import 'dart:typed_data';\n"
"getTypedDataList() {\n"
- " var list = new List(10);\n"
+ " var list = List<dynamic>.filled(10, null);\n"
" var index = 0;\n"
- " list[index++] = new Int8List(256);\n"
- " list[index++] = new Uint8List(256);\n"
- " list[index++] = new Int16List(256);\n"
- " list[index++] = new Uint16List(256);\n"
- " list[index++] = new Int32List(256);\n"
- " list[index++] = new Uint32List(256);\n"
- " list[index++] = new Int64List(256);\n"
- " list[index++] = new Uint64List(256);\n"
- " list[index++] = new Float32List(256);\n"
- " list[index++] = new Float64List(256);\n"
+ " list[index++] = Int8List(256);\n"
+ " list[index++] = Uint8List(256);\n"
+ " list[index++] = Int16List(256);\n"
+ " list[index++] = Uint16List(256);\n"
+ " list[index++] = Int32List(256);\n"
+ " list[index++] = Uint32List(256);\n"
+ " list[index++] = Int64List(256);\n"
+ " list[index++] = Uint64List(256);\n"
+ " list[index++] = Float32List(256);\n"
+ " list[index++] = Float64List(256);\n"
" return list;\n"
"}\n"
"getTypedDataViewList() {\n"
- " var list = new List(30);\n"
+ " var list = List<dynamic>.filled(30, null);\n"
" var index = 0;\n"
- " list[index++] = new Int8List.view(new Int8List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Uint8List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Int16List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Uint16List(256).buffer);\n"
- " list[index++] = new Int32List.view(new Int32List(256).buffer);\n"
- " list[index++] = new Uint32List.view(new Uint32List(256).buffer);\n"
- " list[index++] = new Int64List.view(new Int64List(256).buffer);\n"
- " list[index++] = new Uint64List.view(new Uint64List(256).buffer);\n"
- " list[index++] = new Float32List.view(new Float32List(256).buffer);\n"
- " list[index++] = new Float64List.view(new Float64List(256).buffer);\n"
+ " list[index++] = Int8List.view(Int8List(256).buffer);\n"
+ " list[index++] = Uint8List.view(Uint8List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Int16List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Uint16List(256).buffer);\n"
+ " list[index++] = Int32List.view(new Int32List(256).buffer);\n"
+ " list[index++] = Uint32List.view(new Uint32List(256).buffer);\n"
+ " list[index++] = Int64List.view(new Int64List(256).buffer);\n"
+ " list[index++] = Uint64List.view(new Uint64List(256).buffer);\n"
+ " list[index++] = Float32List.view(new Float32List(256).buffer);\n"
+ " list[index++] = Float64List.view(new Float64List(256).buffer);\n"
- " list[index++] = new Int8List.view(new Int16List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Uint16List(256).buffer);\n"
- " list[index++] = new Int8List.view(new Int32List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Uint32List(256).buffer);\n"
- " list[index++] = new Int8List.view(new Int64List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Uint64List(256).buffer);\n"
- " list[index++] = new Int8List.view(new Float32List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Float32List(256).buffer);\n"
- " list[index++] = new Int8List.view(new Float64List(256).buffer);\n"
- " list[index++] = new Uint8List.view(new Float64List(256).buffer);\n"
+ " list[index++] = Int8List.view(new Int16List(256).buffer);\n"
+ " list[index++] = Uint8List.view(new Uint16List(256).buffer);\n"
+ " list[index++] = Int8List.view(new Int32List(256).buffer);\n"
+ " list[index++] = Uint8List.view(new Uint32List(256).buffer);\n"
+ " list[index++] = Int8List.view(new Int64List(256).buffer);\n"
+ " list[index++] = Uint8List.view(new Uint64List(256).buffer);\n"
+ " list[index++] = Int8List.view(new Float32List(256).buffer);\n"
+ " list[index++] = Uint8List.view(new Float32List(256).buffer);\n"
+ " list[index++] = Int8List.view(new Float64List(256).buffer);\n"
+ " list[index++] = Uint8List.view(new Float64List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Int8List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Uint8List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Int32List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Uint32List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Int64List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Uint64List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Float32List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Float32List(256).buffer);\n"
- " list[index++] = new Int16List.view(new Float64List(256).buffer);\n"
- " list[index++] = new Uint16List.view(new Float64List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Int8List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Uint8List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Int32List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Uint32List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Int64List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Uint64List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Float32List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Float32List(256).buffer);\n"
+ " list[index++] = Int16List.view(new Float64List(256).buffer);\n"
+ " list[index++] = Uint16List.view(new Float64List(256).buffer);\n"
" return list;\n"
"}\n"
"getMultipleTypedDataViewList() {\n"
- " var list = new List(10);\n"
+ " var list = List<dynamic>.filled(10, null);\n"
" var index = 0;\n"
- " var data = new Uint8List(256).buffer;\n"
- " list[index++] = new Int8List.view(data);\n"
- " list[index++] = new Uint8List.view(data);\n"
- " list[index++] = new Int16List.view(data);\n"
- " list[index++] = new Uint16List.view(data);\n"
- " list[index++] = new Int32List.view(data);\n"
- " list[index++] = new Uint32List.view(data);\n"
- " list[index++] = new Int64List.view(data);\n"
- " list[index++] = new Uint64List.view(data);\n"
- " list[index++] = new Float32List.view(data);\n"
- " list[index++] = new Float64List.view(data);\n"
+ " var data = Uint8List(256).buffer;\n"
+ " list[index++] = Int8List.view(data);\n"
+ " list[index++] = Uint8List.view(data);\n"
+ " list[index++] = Int16List.view(data);\n"
+ " list[index++] = Uint16List.view(data);\n"
+ " list[index++] = Int32List.view(data);\n"
+ " list[index++] = Uint32List.view(data);\n"
+ " list[index++] = Int64List.view(data);\n"
+ " list[index++] = Uint64List.view(data);\n"
+ " list[index++] = Float32List.view(data);\n"
+ " list[index++] = Float64List.view(data);\n"
" return list;\n"
"}\n";
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index 15800b7..4b474f5 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -159,86 +159,97 @@
// Unit test case to verify stack frame iteration.
TEST_CASE(ValidateStackFrameIteration) {
- const char* kScriptChars =
- "class StackFrame {"
- " static equals(var obj1, var obj2) native \"StackFrame_equals\";"
- " static int frameCount() native \"StackFrame_frameCount\";"
- " static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
- " static validateFrame(int index,"
- " String name) native \"StackFrame_validateFrame\";"
- "} "
- "class First {"
- " First() { }"
- " int method1(int param) {"
- " if (param == 1) {"
- " param = method2(200);"
- " } else {"
- " param = method2(100);"
- " }"
- " }"
- " int method2(int param) {"
- " if (param == 200) {"
- " First.staticmethod(this, param);"
- " } else {"
- " First.staticmethod(this, 10);"
- " }"
- " }"
- " static int staticmethod(First obj, int param) {"
- " if (param == 10) {"
- " obj.method3(10);"
- " } else {"
- " obj.method3(200);"
- " }"
- " }"
- " method3(int param) {"
- " StackFrame.equals(9, StackFrame.frameCount());"
- " StackFrame.equals(7, StackFrame.dartFrameCount());"
- " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
- " StackFrame.validateFrame(1, \"First_method3\");"
- " StackFrame.validateFrame(2, \"First_staticmethod\");"
- " StackFrame.validateFrame(3, \"First_method2\");"
- " StackFrame.validateFrame(4, \"First_method1\");"
- " StackFrame.validateFrame(5, \"Second_method1\");"
- " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");"
- " }"
- "}"
- "class Second {"
- " Second() { }"
- " int method1(int param) {"
- " if (param == 1) {"
- " param = method2(200);"
- " } else {"
- " First obj = new First();"
- " param = obj.method1(1);"
- " param = obj.method1(2);"
- " }"
- " }"
- " int method2(int param) {"
- " Second.staticmethod(this, param);"
- " }"
- " static int staticmethod(Second obj, int param) {"
- " obj.method3(10);"
- " }"
- " method3(int param) {"
- " StackFrame.equals(8, StackFrame.frameCount());"
- " StackFrame.equals(6, StackFrame.dartFrameCount());"
- " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
- " StackFrame.validateFrame(1, \"Second_method3\");"
- " StackFrame.validateFrame(2, \"Second_staticmethod\");"
- " StackFrame.validateFrame(3, \"Second_method2\");"
- " StackFrame.validateFrame(4, \"Second_method1\");"
- " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");"
- " }"
- "}"
- "class StackFrameTest {"
- " static testMain() {"
- " Second obj = new Second();"
- " obj.method1(1);"
- " obj.method1(2);"
- " }"
- "}";
+ bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong);
+ const char* nullableTag = nullSafety ? "?" : "";
+ // clang-format off
+ auto kScriptChars = Utils::CStringUniquePtr(
+ OS::SCreate(
+ nullptr,
+ "class StackFrame {"
+ " static equals(var obj1, var obj2) native \"StackFrame_equals\";"
+ " static int frameCount() native \"StackFrame_frameCount\";"
+ " static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
+ " static validateFrame(int index,"
+ " String name) native "
+ "\"StackFrame_validateFrame\";"
+ "} "
+ "class First {"
+ " First() { }"
+ " int%s method1(int%s param) {"
+ " if (param == 1) {"
+ " param = method2(200);"
+ " } else {"
+ " param = method2(100);"
+ " }"
+ " }"
+ " int%s method2(int param) {"
+ " if (param == 200) {"
+ " First.staticmethod(this, param);"
+ " } else {"
+ " First.staticmethod(this, 10);"
+ " }"
+ " }"
+ " static int%s staticmethod(First obj, int param) {"
+ " if (param == 10) {"
+ " obj.method3(10);"
+ " } else {"
+ " obj.method3(200);"
+ " }"
+ " }"
+ " method3(int param) {"
+ " StackFrame.equals(9, StackFrame.frameCount());"
+ " StackFrame.equals(7, StackFrame.dartFrameCount());"
+ " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
+ " StackFrame.validateFrame(1, \"First_method3\");"
+ " StackFrame.validateFrame(2, \"First_staticmethod\");"
+ " StackFrame.validateFrame(3, \"First_method2\");"
+ " StackFrame.validateFrame(4, \"First_method1\");"
+ " StackFrame.validateFrame(5, \"Second_method1\");"
+ " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");"
+ " }"
+ "}"
+ "class Second {"
+ " Second() { }"
+ " int%s method1(int%s param) {"
+ " if (param == 1) {"
+ " param = method2(200);"
+ " } else {"
+ " First obj = new First();"
+ " param = obj.method1(1);"
+ " param = obj.method1(2);"
+ " }"
+ " }"
+ " int%s method2(int param) {"
+ " Second.staticmethod(this, param);"
+ " }"
+ " static int%s staticmethod(Second obj, int param) {"
+ " obj.method3(10);"
+ " }"
+ " method3(int param) {"
+ " StackFrame.equals(8, StackFrame.frameCount());"
+ " StackFrame.equals(6, StackFrame.dartFrameCount());"
+ " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
+ " StackFrame.validateFrame(1, \"Second_method3\");"
+ " StackFrame.validateFrame(2, \"Second_staticmethod\");"
+ " StackFrame.validateFrame(3, \"Second_method2\");"
+ " StackFrame.validateFrame(4, \"Second_method1\");"
+ " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");"
+ " }"
+ "}"
+ "class StackFrameTest {"
+ " static testMain() {"
+ " Second obj = new Second();"
+ " obj.method1(1);"
+ " obj.method1(2);"
+ " }"
+ "}",
+ nullableTag, nullableTag, nullableTag, nullableTag, nullableTag,
+ nullableTag, nullableTag, nullableTag),
+ std::free);
+ // clang-format on
Dart_Handle lib = TestCase::LoadTestScript(
- kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
+ kScriptChars.get(),
+ reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest"));
EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL));
}
diff --git a/runtime/vm/v8_snapshot_writer.cc b/runtime/vm/v8_snapshot_writer.cc
index 7d22307..4f4c1c1 100644
--- a/runtime/vm/v8_snapshot_writer.cc
+++ b/runtime/vm/v8_snapshot_writer.cc
@@ -34,6 +34,16 @@
strings_.Insert({"<unknown>", kUnknownString});
strings_.Insert({"<artificial root>", kArtificialRootString});
+
+ nodes_.Insert({ArtificialRootId(),
+ {
+ kArtificialRoot,
+ kArtificialRootString,
+ ArtificialRootId(),
+ 0,
+ nullptr,
+ 0,
+ }});
}
void V8SnapshotProfileWriter::SetObjectTypeAndName(ObjectId object_id,
@@ -90,10 +100,9 @@
};
}
-V8SnapshotProfileWriter::NodeInfo V8SnapshotProfileWriter::ArtificialRoot() {
- return {
- kArtificialRoot, kArtificialRootString, {kArtificial, 0}, 0, nullptr, 0,
- };
+const V8SnapshotProfileWriter::NodeInfo&
+V8SnapshotProfileWriter::ArtificialRoot() {
+ return nodes_.Lookup(ArtificialRootId())->value;
}
V8SnapshotProfileWriter::NodeInfo* V8SnapshotProfileWriter::EnsureId(
@@ -212,8 +221,7 @@
writer->CloseObject();
- writer->PrintProperty64("node_count",
- nodes_.Size() + 1 /* artificial root */);
+ writer->PrintProperty64("node_count", nodes_.Size());
writer->PrintProperty64("edge_count", edge_count_ + roots_.Size());
}
writer->CloseObject();
@@ -227,6 +235,9 @@
auto it = nodes_.GetIterator();
while ((entry = it.Next()) != nullptr) {
ASSERT(entry->key == entry->value.id);
+ if (entry->value.id == ArtificialRootId()) {
+ continue; // Written separately above.
+ }
entry->value.offset = offset;
WriteNodeInfo(writer, entry->value);
offset += kNumNodeFields;
@@ -250,6 +261,10 @@
auto nodes_it = nodes_.GetIterator();
while ((entry = nodes_it.Next()) != nullptr) {
+ if (entry->value.edges == nullptr) {
+ continue; // Artificial root, its edges are written separately above.
+ }
+
for (intptr_t i = 0; i < entry->value.edges->length(); ++i) {
WriteEdgeInfo(writer, entry->value.edges->At(i));
}
diff --git a/runtime/vm/v8_snapshot_writer.h b/runtime/vm/v8_snapshot_writer.h
index 98f19ed..34486ff 100644
--- a/runtime/vm/v8_snapshot_writer.h
+++ b/runtime/vm/v8_snapshot_writer.h
@@ -105,6 +105,8 @@
intptr_t EnsureString(const char* str);
+ static ObjectId ArtificialRootId() { return {kArtificial, 0}; }
+
private:
static constexpr intptr_t kNumNodeFields = 5;
static constexpr intptr_t kNumEdgeFields = 3;
@@ -145,7 +147,7 @@
};
NodeInfo DefaultNode(ObjectId object_id);
- static NodeInfo ArtificialRoot();
+ const NodeInfo& ArtificialRoot();
NodeInfo* EnsureId(ObjectId object_id);
static intptr_t NodeIdFor(ObjectId id) {
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index de44234..b5b010a 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -99,6 +99,7 @@
* for String examples and recipes.
* * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions)
*/
+@pragma('vm:entry-point')
abstract class String implements Comparable<String>, Pattern {
/**
* Allocates a new String for the specified [charCodes].
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index f9f0f63..770d1bf 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -102,10 +102,6 @@
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external int get value;
- /// The 8-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
- /// being stored, and the 8-bit value is sign-extended when it is loaded.
external void set value(int value);
/// The 8-bit two's complement integer at `address + index`.
@@ -140,12 +136,6 @@
/// The [address] must be 2-byte aligned.
external int get value;
- /// The 16-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
- /// being stored, and the 16-bit value is sign-extended when it is loaded.
- ///
- /// The [address] must be 2-byte aligned.
external void set value(int value);
/// The 16-bit two's complement integer at `address + 2 * index`.
@@ -186,12 +176,6 @@
/// The [address] must be 4-byte aligned.
external int get value;
- /// The 32-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
- /// being stored, and the 32-bit value is sign-extended when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(int value);
/// The 32-bit two's complement integer at `address + 4 * index`.
@@ -229,9 +213,6 @@
/// The [address] must be 8-byte aligned.
external int get value;
- /// The 64-bit two's complement integer at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(int value);
/// The 64-bit two's complement integer at `address + 8 * index`.
@@ -264,10 +245,6 @@
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external int get value;
- /// The 8-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
- /// being stored, and the 8-bit value is zero-extended when it is loaded.
external void set value(int value);
/// The 8-bit unsigned integer at `address + index`.
@@ -302,12 +279,6 @@
/// The [address] must be 2-byte aligned.
external int get value;
- /// The 16-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
- /// being stored, and the 16-bit value is zero-extended when it is loaded.
- ///
- /// The [address] must be 2-byte aligned.
external void set value(int value);
/// The 16-bit unsigned integer at `address + 2 * index`.
@@ -348,12 +319,6 @@
/// The [address] must be 4-byte aligned.
external int get value;
- /// The 32-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
- /// being stored, and the 32-bit value is zero-extended when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(int value);
/// The 32-bit unsigned integer at `address + 4 * index`.
@@ -391,9 +356,6 @@
/// The [address] must be 8-byte aligned.
external int get value;
- /// The 64-bit unsigned integer at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(int value);
/// The 64-bit unsigned integer at `address + 8 * index`.
@@ -433,17 +395,6 @@
/// platforms the [address] must be 8-byte aligned.
external int get value;
- /// The 32 or 64-bit two's complement integer at [address].
- ///
- /// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms
- /// this is a 64-bit integer.
- ///
- /// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by
- /// `.toSigned(32)`) before being stored, and the 32-bit value is
- /// sign-extended when it is loaded.
- ///
- /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
- /// platforms the [address] must be 8-byte aligned.
external void set value(int value);
/// The 32 or 64-bit two's complement integer at `address + (4 or 8) * index`.
@@ -483,12 +434,6 @@
/// The [address] must be 4-byte aligned.
external double get value;
- /// The float at [address].
- ///
- /// A Dart double loses precision before being stored, and the float value is
- /// converted to a double when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(double value);
/// The float at `address + 4 * index`.
@@ -526,9 +471,6 @@
/// The [address] must be 8-byte aligned.
external double get value;
- /// The double at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(double value);
/// The double at `address + 8 * index`.
@@ -568,13 +510,6 @@
/// platforms the [address] must be 8-byte aligned.
external Pointer<T> get value;
- /// Store a Dart value into this location.
- ///
- /// A [Pointer] is unboxed before being stored (as if by `.address`), and the
- /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
- ///
- /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
- /// platforms the [address] must be 8-byte aligned.
external void set value(Pointer<T> value);
/// Load a Dart value from this location offset by [index].
diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart
index c9cc847..b7bba38 100644
--- a/sdk_nnbd/lib/core/string.dart
+++ b/sdk_nnbd/lib/core/string.dart
@@ -97,6 +97,7 @@
* for String examples and recipes.
* * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions)
*/
+@pragma('vm:entry-point')
abstract class String implements Comparable<String>, Pattern {
/**
* Allocates a new String for the specified [charCodes].
diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart
index 202f4f6..3b6e236 100644
--- a/sdk_nnbd/lib/ffi/ffi.dart
+++ b/sdk_nnbd/lib/ffi/ffi.dart
@@ -101,10 +101,6 @@
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external int get value;
- /// The 8-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
- /// being stored, and the 8-bit value is sign-extended when it is loaded.
external void set value(int value);
/// The 8-bit two's complement integer at `address + index`.
@@ -139,12 +135,6 @@
/// The [address] must be 2-byte aligned.
external int get value;
- /// The 16-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
- /// being stored, and the 16-bit value is sign-extended when it is loaded.
- ///
- /// The [address] must be 2-byte aligned.
external void set value(int value);
/// The 16-bit two's complement integer at `address + 2 * index`.
@@ -185,12 +175,6 @@
/// The [address] must be 4-byte aligned.
external int get value;
- /// The 32-bit two's complement integer at [address].
- ///
- /// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
- /// being stored, and the 32-bit value is sign-extended when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(int value);
/// The 32-bit two's complement integer at `address + 4 * index`.
@@ -228,9 +212,6 @@
/// The [address] must be 8-byte aligned.
external int get value;
- /// The 64-bit two's complement integer at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(int value);
/// The 64-bit two's complement integer at `address + 8 * index`.
@@ -263,10 +244,6 @@
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external int get value;
- /// The 8-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
- /// being stored, and the 8-bit value is zero-extended when it is loaded.
external void set value(int value);
/// The 8-bit unsigned integer at `address + index`.
@@ -301,12 +278,6 @@
/// The [address] must be 2-byte aligned.
external int get value;
- /// The 16-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
- /// being stored, and the 16-bit value is zero-extended when it is loaded.
- ///
- /// The [address] must be 2-byte aligned.
external void set value(int value);
/// The 16-bit unsigned integer at `address + 2 * index`.
@@ -347,12 +318,6 @@
/// The [address] must be 4-byte aligned.
external int get value;
- /// The 32-bit unsigned integer at [address].
- ///
- /// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
- /// being stored, and the 32-bit value is zero-extended when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(int value);
/// The 32-bit unsigned integer at `address + 4 * index`.
@@ -390,9 +355,6 @@
/// The [address] must be 8-byte aligned.
external int get value;
- /// The 64-bit unsigned integer at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(int value);
/// The 64-bit unsigned integer at `address + 8 * index`.
@@ -432,17 +394,6 @@
/// platforms the [address] must be 8-byte aligned.
external int get value;
- /// The 32 or 64-bit two's complement integer at [address].
- ///
- /// On 32-bit platforms this is a 32-bit integer, and on 64-bit platforms
- /// this is a 64-bit integer.
- ///
- /// On 32-bit platforms a Dart integer is truncated to 32 bits (as if by
- /// `.toSigned(32)`) before being stored, and the 32-bit value is
- /// sign-extended when it is loaded.
- ///
- /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
- /// platforms the [address] must be 8-byte aligned.
external void set value(int value);
/// The 32 or 64-bit two's complement integer at `address + (4 or 8) * index`.
@@ -482,12 +433,6 @@
/// The [address] must be 4-byte aligned.
external double get value;
- /// The float at [address].
- ///
- /// A Dart double loses precision before being stored, and the float value is
- /// converted to a double when it is loaded.
- ///
- /// The [address] must be 4-byte aligned.
external void set value(double value);
/// The float at `address + 4 * index`.
@@ -525,9 +470,6 @@
/// The [address] must be 8-byte aligned.
external double get value;
- /// The double at [address].
- ///
- /// The [address] must be 8-byte aligned.
external void set value(double value);
/// The double at `address + 8 * index`.
@@ -567,13 +509,6 @@
/// platforms the [address] must be 8-byte aligned.
external Pointer<T> get value;
- /// Store a Dart value into this location.
- ///
- /// A [Pointer] is unboxed before being stored (as if by `.address`), and the
- /// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
- ///
- /// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
- /// platforms the [address] must be 8-byte aligned.
external void set value(Pointer<T> value);
/// Load a Dart value from this location offset by [index].
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 78c548d..798ffdd 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -6,8 +6,6 @@
Language/Classes/Abstract_Instance_Members/*: Skip # Not migrated to NNBD
Language/Classes/Class_Member_Conflicts/*: Skip # Not migrated to NNBD
Language/Classes/Constructors/*: Skip # Not migrated to NNBD
-Language/Classes/Constructors/Constant_Constructors/*: Skip # Not migrated to NNBD
-Language/Classes/Constructors/Factories/*: Skip # Not migrated to NNBD
Language/Classes/Constructors/Generative_Constructors/*: Skip # Not migrated to NNBD
Language/Classes/Getters/*: Skip # Not migrated to NNBD
Language/Classes/Instance_Methods/*: Skip # Not migrated to NNBD
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 7269570..36cf01d 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -94,7 +94,7 @@
new C5<num>().F18();
}
"""),
- options: [Flags.printLegacyStars]);
+ options: [Flags.noSoundNullSafety, Flags.printLegacyStars]);
var types = env.types;
diff --git a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
index 3584feb..c61a86b 100644
--- a/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
+++ b/tests/compiler/dart2js/generic_methods/generic_method_type_test.dart
@@ -5,6 +5,7 @@
// @dart = 2.7
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/universe/call_structure.dart';
@@ -32,7 +33,7 @@
${createUses(signatures, prefix: 't')}
${createUses(signatures, prefix: 'm')}
}
- """);
+ """, options: [Flags.noSoundNullSafety]);
for (FunctionTypeData data in signatures) {
DartType functionType = env.getElementType('t${data.name}');
diff --git a/tests/compiler/dart2js/model/future_or_test.dart b/tests/compiler/dart2js/model/future_or_test.dart
index 30e126a..1d8e384 100644
--- a/tests/compiler/dart2js/model/future_or_test.dart
+++ b/tests/compiler/dart2js/model/future_or_test.dart
@@ -5,6 +5,7 @@
// @dart = 2.7
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:expect/expect.dart';
@@ -52,7 +53,7 @@
new C().futureT();
new C().futureOrT();
}
-""");
+""", options: [Flags.noSoundNullSafety]);
FunctionType getFunctionType(String name, String expectedType,
[ClassEntity cls]) {
FunctionType type = env.getMemberType(name, cls);
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index f166770..3d88054 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -8,6 +8,7 @@
import 'dart:async';
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart' show ClassEntity;
import 'package:compiler/src/elements/types.dart';
import 'package:expect/expect.dart';
@@ -60,7 +61,8 @@
main() {
new C();
}
- """, expectNoErrors: true).then((env) {
+ """, options: [Flags.noSoundNullSafety], expectNoErrors: true)
+ .then((env) {
void expect(bool expectSubtype, DartType T, DartType S) {
testTypes(env, T, S, expectSubtype);
}
@@ -318,7 +320,8 @@
a.m4(null, null);
a.m5(null, null);
}
- """, expectNoErrors: true).then((env) {
+ """, options: [Flags.noSoundNullSafety], expectNoErrors: true)
+ .then((env) {
void expect(bool expectSubtype, DartType T, DartType S) {
testTypes(env, T, S, expectSubtype);
}
@@ -371,6 +374,7 @@
${createUses(functionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then(functionSubtypingHelper);
}
@@ -382,6 +386,7 @@
${createUses(functionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then(functionSubtypingHelper);
}
@@ -464,6 +469,7 @@
${createUses(optionalFunctionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then((env) => functionSubtypingOptionalHelper(env));
}
@@ -475,6 +481,7 @@
${createUses(optionalFunctionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then((env) => functionSubtypingOptionalHelper(env));
}
@@ -545,6 +552,7 @@
${createUses(namedFunctionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then((env) => functionSubtypingNamedHelper(env));
}
@@ -556,6 +564,7 @@
${createUses(namedFunctionTypesData)}
}
"""),
+ options: [Flags.noSoundNullSafety],
expectNoErrors: true)
.then((env) => functionSubtypingNamedHelper(env));
}
@@ -612,7 +621,8 @@
new E<int, num>();
new F();
}
- """, expectNoErrors: true).then((env) {
+ """, options: [Flags.noSoundNullSafety], expectNoErrors: true)
+ .then((env) {
void expect(bool expectSubtype, DartType T, DartType S) {
testTypes(env, T, S, expectSubtype);
}
@@ -745,7 +755,8 @@
takeVoid(null);
takeObject(null);
}
- """, expectNoErrors: true).then((env) {
+ """, options: [Flags.noSoundNullSafety], expectNoErrors: true)
+ .then((env) {
void expect(bool expectSubtype, DartType T, DartType S) {
Expect.equals(expectSubtype, env.isSubtype(T, S), '$T <: $S');
if (expectSubtype) {
diff --git a/tests/compiler/dart2js/model/type_substitution_test.dart b/tests/compiler/dart2js/model/type_substitution_test.dart
index 9072baa..ff3aae1 100644
--- a/tests/compiler/dart2js/model/type_substitution_test.dart
+++ b/tests/compiler/dart2js/model/type_substitution_test.dart
@@ -8,6 +8,7 @@
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
@@ -59,7 +60,7 @@
new E();
new F();
}
- ''');
+ ''', options: [Flags.noSoundNullSafety]);
var types = env.types;
ClassEntity A = env.getElement("A");
ClassEntity B = env.getElement("B");
@@ -122,7 +123,7 @@
class Class<T,S> {}
main() => new Class();
- """);
+ """, options: [Flags.noSoundNullSafety]);
var types = env.types;
InterfaceType Class_T_S = env["Class"];
Expect.isNotNull(Class_T_S);
diff --git a/tests/language/call/constructor_on_unresolvable_class_test.dart b/tests/language/call/constructor_on_unresolvable_class_test.dart
index d068b53..f3fa482 100644
--- a/tests/language/call/constructor_on_unresolvable_class_test.dart
+++ b/tests/language/call/constructor_on_unresolvable_class_test.dart
@@ -11,14 +11,14 @@
main() {
new A();
// ^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A'.
new A.foo();
// ^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A.foo'.
new lib.A();
// ^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'lib.A'.
}
diff --git a/tests/language/class/variable_shadow_class_test.dart b/tests/language/class/variable_shadow_class_test.dart
index d82fef7..35a1fda 100644
--- a/tests/language/class/variable_shadow_class_test.dart
+++ b/tests/language/class/variable_shadow_class_test.dart
@@ -15,8 +15,9 @@
var Test;
// Now this refers to the variable.
var i = new Test.named(10);
- // ^^^^
+ // ^^^^^^^^^^
// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+ // ^^^^
// [cfe] Method not found: 'Test.named'.
Expect.equals(10, i.field);
}
diff --git a/tests/language/constructor/reference_test.dart b/tests/language/constructor/reference_test.dart
index 52e1235..cecfbf3 100644
--- a/tests/language/constructor/reference_test.dart
+++ b/tests/language/constructor/reference_test.dart
@@ -13,7 +13,7 @@
new Foo.bar();
new Foo.bar.baz();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
new Foo<int>();
@@ -33,13 +33,13 @@
new Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+ // ^^^^^^^
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
new Foo.bar.baz<int>();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^^^
// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
// [cfe] A constructor invocation can't have type arguments on the constructor name.
@@ -50,7 +50,7 @@
const Foo.bar();
const Foo.bar.baz();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
const Foo<int>();
@@ -70,13 +70,13 @@
const Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+ // ^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
const Foo.bar.baz<int>();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^^^
// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
// [cfe] A constructor invocation can't have type arguments on the constructor name.
@@ -106,8 +106,8 @@
Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+//^^^^^^^
+// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
Foo.bar.baz<int>();
diff --git a/tests/language/import/collection_no_prefix_test.dart b/tests/language/import/collection_no_prefix_test.dart
new file mode 100644
index 0000000..cf4f490
--- /dev/null
+++ b/tests/language/import/collection_no_prefix_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program importing the core library explicitly.
+
+library ImportCollectionNoPrefixTest.dart;
+
+import "dart:collection";
+
+main() {
+ var e = new SplayTreeMap();
+ print('"dart:collection" imported, $e allocated');
+}
diff --git a/tests/language/import/combinators2_runtime_test.dart b/tests/language/import/combinators2_runtime_test.dart
new file mode 100644
index 0000000..ec0051d
--- /dev/null
+++ b/tests/language/import/combinators2_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program importing with show/hide combinators.
+
+// Show "hide" and "show", hide "ugly".
+import "import1_lib.dart" show hide, show hide ugly;
+
+main() {
+ print(hide);
+ print(show);
+
+ // Ugly is hidden.
+
+}
diff --git a/tests/language/import/combinators2_test.dart b/tests/language/import/combinators2_test.dart
new file mode 100644
index 0000000..47a2db0
--- /dev/null
+++ b/tests/language/import/combinators2_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program importing with show/hide combinators.
+
+// Show "hide" and "show", hide "ugly".
+import "import1_lib.dart" show hide, show hide ugly;
+
+main() {
+ print(hide);
+ print(show);
+
+ // Ugly is hidden.
+ print(ugly);
+ // ^^^^
+ // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ // [cfe] Getter not found: 'ugly'.
+}
diff --git a/tests/language/import/combinators_part.dart b/tests/language/import/combinators_part.dart
new file mode 100644
index 0000000..9db5453
--- /dev/null
+++ b/tests/language/import/combinators_part.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file is part of the test import_combinators_test.dart
+
+part of importCombinatorsTest;
+
+lookBehindCurtain() {
+ return show; // show is an imported identifier.
+}
diff --git a/tests/language/import/combinators_test.dart b/tests/language/import/combinators_test.dart
new file mode 100644
index 0000000..c330983
--- /dev/null
+++ b/tests/language/import/combinators_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program importing with show/hide combinators.
+
+library importCombinatorsTest;
+
+import "package:expect/expect.dart";
+import "import1_lib.dart" show hide, show hide ugly;
+import "export1_lib.dart";
+import "dart:math" as M show e;
+
+part "combinators_part.dart";
+
+main() {
+ Expect.equals("hide", hide);
+ Expect.equals("show", show);
+ // Top-level function from part, refers to imported variable show.
+ Expect.equals("show", lookBehindCurtain());
+ // Top-level variable E from export1_lib.dart.
+ Expect.equals("E", e);
+ // Top-level variable E imported from dart:math.
+ Expect.equals(2.718281828459045, M.e);
+ // Constant LN2 from math library, re-exported by export1_lib.dart.
+ Expect.equals(0.6931471805599453, ln2);
+}
diff --git a/tests/language/import/conditional_import_test.dart b/tests/language/import/conditional_import_test.dart
new file mode 100644
index 0000000..4aa3b31
--- /dev/null
+++ b/tests/language/import/conditional_import_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+// All three libraries have an HttpRequest class.
+import "conditional_import_test.dart"
+ if (dart.library.io) "dart:io"
+ if (dart.library.html) "dart:html" deferred as d show HttpRequest;
+
+class HttpRequest {}
+
+void main() {
+ asyncStart();
+ var io = const bool.fromEnvironment("dart.library.io");
+ var html = const bool.fromEnvironment("dart.library.html");
+ () async {
+ // Shouldn't fail. Shouldn't time out.
+ await d.loadLibrary().timeout(const Duration(seconds: 5));
+ if (io) {
+ print("io");
+ Expect.throws(() => new d.HttpRequest()); // Class is abstract in dart:io
+ } else if (html) {
+ print("html");
+ dynamic r = new d.HttpRequest(); // Shouldn't throw
+ var o = r.open; // Shouldn't fail, the open method is there.
+ } else {
+ print("none");
+ dynamic r = new d.HttpRequest();
+ Expect.isTrue(r is HttpRequest);
+ }
+ asyncEnd();
+ }();
+}
diff --git a/tests/language/import/conditional_string_test.dart b/tests/language/import/conditional_string_test.dart
new file mode 100644
index 0000000..2eafa52
--- /dev/null
+++ b/tests/language/import/conditional_string_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+// All three libraries have an HttpRequest class.
+import "conditional_string_test.dart"
+ if (dart.library.io == "true") "dart:io"
+ if (dart.library.html == "true") "dart:html" deferred as d show HttpRequest;
+
+class HttpRequest {}
+
+void main() {
+ asyncStart();
+ var io = const String.fromEnvironment("dart.library.io");
+ var html = const String.fromEnvironment("dart.library.html");
+ () async {
+ // Shouldn't fail. Shouldn't time out.
+ await d.loadLibrary().timeout(const Duration(seconds: 5));
+ if (io == "true") {
+ print("io");
+ Expect.throws(() => new d.HttpRequest()); // Class is abstract in dart:io
+ } else if (html == "true") {
+ print("html");
+ dynamic r = new d.HttpRequest(); // Shouldn't throw
+ var o = r.open; // Shouldn't fail, the open method is there.
+ } else {
+ print("none");
+ dynamic r = new d.HttpRequest();
+ Expect.isTrue(r is HttpRequest);
+ }
+ asyncEnd();
+ }();
+}
diff --git a/tests/language/import/config_corelib_general.dart b/tests/language/import/config_corelib_general.dart
new file mode 100644
index 0000000..295f09a
--- /dev/null
+++ b/tests/language/import/config_corelib_general.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Classy {
+ String get name => "classy general";
+ String httpSpecific() => throw UnimplementedError();
+ String ioSpecific() => throw UnimplementedError();
+}
+
+bool general() => true;
+bool httpSpecific() => false;
+bool ioSpecific() => false;
+final String name = "general";
diff --git a/tests/language/import/config_corelib_http.dart b/tests/language/import/config_corelib_http.dart
new file mode 100644
index 0000000..857e391
--- /dev/null
+++ b/tests/language/import/config_corelib_http.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, 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:http";
+
+class Classy {
+ String get name => "classy http";
+ String httpSpecific() => "classy http";
+ String ioSpecific() => throw UnimplementedError();
+}
+
+bool general() => true;
+bool httpSpecific() => true;
+bool ioSpecific() => false;
+final String name = "http";
diff --git a/tests/language/import/config_corelib_io.dart b/tests/language/import/config_corelib_io.dart
new file mode 100644
index 0000000..5e1543d
--- /dev/null
+++ b/tests/language/import/config_corelib_io.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+
+class Classy {
+ String get name => "classy io";
+ String httpSpecific() => throw UnimplementedError();
+ String ioSpecific() => "classy io";
+}
+
+bool general() => true;
+bool httpSpecific() => false;
+bool ioSpecific() => true;
+final String name = "io";
diff --git a/tests/language/import/config_corelib_test.dart b/tests/language/import/config_corelib_test.dart
new file mode 100644
index 0000000..362e41e
--- /dev/null
+++ b/tests/language/import/config_corelib_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, 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:expect/expect.dart';
+
+import 'config_corelib_general.dart'
+ if (dart.library.io) 'config_corelib_io.dart'
+ if (dart.library.http) 'config_corelib_http.dart' as lib;
+
+class SubClassy extends lib.Classy {
+ String get superName => super.name;
+}
+
+main() {
+ var io = const bool.fromEnvironment("dart.library.io");
+ var http = const bool.fromEnvironment("dart.library.http");
+
+ var cy = new SubClassy();
+
+ if (io) {
+ Expect.isTrue(lib.general());
+ Expect.equals("io", lib.name);
+ Expect.equals("classy io", cy.name);
+
+ Expect.isTrue(lib.ioSpecific());
+ Expect.equals("classy io", cy.ioSpecific());
+
+ Expect.isFalse(lib.httpSpecific());
+ Expect.throws(cy.httpSpecific);
+ } else if (http) {
+ Expect.isTrue(lib.general());
+ Expect.equals("http", lib.name);
+ Expect.equals("classy http", cy.name);
+
+ Expect.isFalse(lib.ioSpecific());
+ Expect.throws(cy.ioSpecific);
+
+ Expect.isTrue(lib.httpSpecific());
+ Expect.equals("classy http", cy.httpSpecific());
+ } else {
+ Expect.isTrue(lib.general());
+ Expect.equals("general", lib.name);
+ Expect.equals("classy general", cy.name);
+
+ Expect.isFalse(lib.ioSpecific());
+ Expect.throws(cy.ioSpecific);
+
+ Expect.isFalse(lib.httpSpecific());
+ Expect.throws(cy.httpSpecific);
+ }
+}
diff --git a/tests/language/import/core_no_prefix_test.dart b/tests/language/import/core_no_prefix_test.dart
new file mode 100644
index 0000000..254744f
--- /dev/null
+++ b/tests/language/import/core_no_prefix_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program importing the core library explicitly.
+
+library ImportCoreNoPrefixTest.dart;
+
+import "dart:core";
+
+main() {
+ print('"dart:core" imported.');
+}
diff --git a/tests/language/import/core_prefix_test.dart b/tests/language/import/core_prefix_test.dart
new file mode 100644
index 0000000..0f3374b
--- /dev/null
+++ b/tests/language/import/core_prefix_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test explicit import of dart:core in the source code..
+
+library ImportCorePrefixTest.dart;
+
+import "package:expect/expect.dart";
+import "dart:core" as mycore;
+
+class Object {}
+
+class Map {
+ Map(this._lat, this._long);
+
+ get isPrimeMeridian => _long == 0;
+
+ var _lat;
+ var _long;
+}
+
+void main() {
+ var test = new mycore.Map<mycore.int, mycore.String>();
+ mycore.bool boolval = false;
+ mycore.int variable = 10;
+ mycore.num value = 10;
+ mycore.dynamic d = null;
+ mycore.print(new mycore.Object());
+ mycore.print(new Object());
+
+ var greenwich = new Map(51, 0);
+ var kpao = new Map(37, -122);
+ Expect.isTrue(greenwich.isPrimeMeridian);
+ Expect.isFalse(kpao.isPrimeMeridian);
+}
diff --git a/tests/language/import/core_test.dart b/tests/language/import/core_test.dart
new file mode 100644
index 0000000..1256012
--- /dev/null
+++ b/tests/language/import/core_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test explicit import of dart:core in the source code..
+
+library ImportCoreTest.dart;
+
+import "dart:core";
+
+void main() {
+ var test = new Map<int, String>();
+ bool value = false;
+ int variable = 10;
+ num intval = 10;
+}
diff --git a/tests/language/import/cyclic_test.dart b/tests/language/import/cyclic_test.dart
new file mode 100644
index 0000000..d266b87
--- /dev/null
+++ b/tests/language/import/cyclic_test.dart
@@ -0,0 +1,9 @@
+library CyclicImportTest;
+
+import 'sub/sub.dart';
+
+var value = 42;
+
+main() {
+ subMain();
+}
diff --git a/tests/language/import/duplicate_import_liba.dart b/tests/language/import/duplicate_import_liba.dart
new file mode 100644
index 0000000..b8af1a7
--- /dev/null
+++ b/tests/language/import/duplicate_import_liba.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, 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 liba;
+
+var field;
+
+void method() {}
+
+class Class {}
+
+void methodOrClass() {}
diff --git a/tests/language/import/duplicate_libb.dart b/tests/language/import/duplicate_libb.dart
new file mode 100644
index 0000000..456147f
--- /dev/null
+++ b/tests/language/import/duplicate_libb.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2012, 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 libb;
+
+var field;
+
+void method() {}
+
+class Class {}
+
+class methodOrClass {}
diff --git a/tests/language/import/duplicate_prefix_test.dart b/tests/language/import/duplicate_prefix_test.dart
new file mode 100644
index 0000000..bb5a36c
--- /dev/null
+++ b/tests/language/import/duplicate_prefix_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, 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.
+
+// Importing with a duplicate prefix is allowed.
+
+import "duplicate_import_liba.dart" as a;
+import "duplicate_libb.dart" as a;
+
+void main() {}
diff --git a/tests/language/import/export1_lib.dart b/tests/language/import/export1_lib.dart
new file mode 100644
index 0000000..3f7be5b
--- /dev/null
+++ b/tests/language/import/export1_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2012, 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 export1_lib;
+
+export "dart:math" show ln10, ln2, e;
+
+var e = "E"; // Hides constant E from math lib.
diff --git a/tests/language/import/hidden_import_test.dart b/tests/language/import/hidden_import_test.dart
new file mode 100644
index 0000000..4c51a19
--- /dev/null
+++ b/tests/language/import/hidden_import_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that dart: imports are implicitly hidden and cause warning on use.
+
+library hidden_import;
+
+import 'hidden_lib.dart';
+import 'hidden_lib.dart' as prefix;
+import 'dart:async';
+import 'dart:async' as prefix;
+
+main() {
+ new Future();
+ new prefix.Future();
+}
diff --git a/tests/language/import/hidden_lib.dart b/tests/language/import/hidden_lib.dart
new file mode 100644
index 0000000..de7f2df
--- /dev/null
+++ b/tests/language/import/hidden_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2013, 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 hidden_import_lib;
+
+class Future {}
diff --git a/tests/language/import/hidden_runtime_test.dart b/tests/language/import/hidden_runtime_test.dart
new file mode 100644
index 0000000..6a9964e
--- /dev/null
+++ b/tests/language/import/hidden_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests that dart: imports are implicitly hidden and cause warning on use.
+
+library hidden_import;
+
+import 'hidden_lib.dart';
+import 'hidden_lib.dart' as prefix;
+import 'dart:async';
+import 'dart:async' as prefix;
+
+main() {
+
+
+}
diff --git a/tests/language/import/import1_lib.dart b/tests/language/import/import1_lib.dart
new file mode 100644
index 0000000..bf45808
--- /dev/null
+++ b/tests/language/import/import1_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2012, 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 import1_lib;
+
+int libfunc(a, b) => a + b;
+
+var show = 'show';
+var hide = 'hide';
+
+var ugly = 'ugly';
+
+class Q {
+ var _s;
+ Q(s) : _s = s;
+ toString() => "LQQK: '$_s'";
+}
diff --git a/tests/language/import/internal_library_runtime_test.dart b/tests/language/import/internal_library_runtime_test.dart
new file mode 100644
index 0000000..a0e4c23
--- /dev/null
+++ b/tests/language/import/internal_library_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a private library cannot be accessed from outside the platform.
+
+library internal_library_test;
+
+import 'dart:core'; // This loads 'dart:_foreign_helper' and 'patch:core'.
+
+
+
+
+void main() {
+
+
+}
diff --git a/tests/language/import/internal_library_test.dart b/tests/language/import/internal_library_test.dart
new file mode 100644
index 0000000..4983fd9
--- /dev/null
+++ b/tests/language/import/internal_library_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a private library cannot be accessed from outside the platform.
+
+library internal_library_test;
+
+import 'dart:core'; // This loads 'dart:_foreign_helper' and 'patch:core'.
+import 'dart:_foreign_helper';
+// ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.IMPORT_INTERNAL_LIBRARY
+// [cfe] Can't access platform private library.
+// ^
+// [cfe] Not found: 'dart:_foreign_helper'
+
+part 'dart:_foreign_helper';
+// ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.PART_OF_NON_PART
+// [cfe] Can't access platform private library.
+// ^
+// [cfe] Can't use 'org-dartlang-untranslatable-uri:dart%3A_foreign_helper' as a part, because it has no 'part of' declaration.
+// ^
+// [cfe] Not found: 'dart:_foreign_helper'
+
+void main() {
+ JS('int', '0');
+//^
+// [cfe] Method not found: 'JS'.
+ JS('int', '0');
+//^
+// [cfe] Method not found: 'JS'.
+}
diff --git a/tests/language/import/nonexisting_dart_uri_runtime_test.dart b/tests/language/import/nonexisting_dart_uri_runtime_test.dart
new file mode 100644
index 0000000..f31c56d
--- /dev/null
+++ b/tests/language/import/nonexisting_dart_uri_runtime_test.dart
@@ -0,0 +1,10 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+
+main() {}
diff --git a/tests/language/import/nonexisting_dart_uri_test.dart b/tests/language/import/nonexisting_dart_uri_test.dart
new file mode 100644
index 0000000..cb25b61
--- /dev/null
+++ b/tests/language/import/nonexisting_dart_uri_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, 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:nonexisting/nonexisting.dart";
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.URI_DOES_NOT_EXIST
+// [cfe] Not found: 'dart:nonexisting/nonexisting.dart'
+
+main() {}
diff --git a/tests/language/import/private_runtime_test.dart b/tests/language/import/private_runtime_test.dart
new file mode 100644
index 0000000..81914a9
--- /dev/null
+++ b/tests/language/import/private_runtime_test.dart
@@ -0,0 +1,13 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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.
+// Check that private dart:_ libraries cannot be imported.
+
+
+
+main() {
+ print("Done.");
+}
diff --git a/tests/language/import/private_test.dart b/tests/language/import/private_test.dart
new file mode 100644
index 0000000..deb2f1e
--- /dev/null
+++ b/tests/language/import/private_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, 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.
+// Check that private dart:_ libraries cannot be imported.
+
+import "dart:_internal";
+// ^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.IMPORT_INTERNAL_LIBRARY
+// [cfe] Can't access platform private library.
+
+main() {
+ print("Done.");
+}
diff --git a/tests/language/import/self_runtime_test.dart b/tests/language/import/self_runtime_test.dart
new file mode 100644
index 0000000..47dac6e
--- /dev/null
+++ b/tests/language/import/self_runtime_test.dart
@@ -0,0 +1,23 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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.
+//
+// Check that private names cannot be imported even if the library imports
+// itself.
+
+library import_self;
+
+import "package:expect/expect.dart";
+
+// Eliminate the import of the unmodified file or else the analyzer
+// will generate the static error in the import_self_test_none case.
+
+
+var _x = "The quick brown fox jumps over the dazy log";
+
+main() {
+
+}
diff --git a/tests/language/import/self_test.dart b/tests/language/import/self_test.dart
new file mode 100644
index 0000000..1feeb88
--- /dev/null
+++ b/tests/language/import/self_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, 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.
+//
+// Check that private names cannot be imported even if the library imports
+// itself.
+
+library import_self;
+
+import "package:expect/expect.dart";
+
+// Eliminate the import of the unmodified file or else the analyzer
+// will generate the static error in the import_self_test_none case.
+import "self_test.dart" as p;
+
+var _x = "The quick brown fox jumps over the dazy log";
+
+main() {
+ p._x;
+ //^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_PREFIXED_NAME
+ // [cfe] Getter not found: '_x'.
+}
diff --git a/tests/language/import/show_lib.dart b/tests/language/import/show_lib.dart
new file mode 100644
index 0000000..a3d7325
--- /dev/null
+++ b/tests/language/import/show_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2013, 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 import_show_lib;
+
+get theEnd => "http://www.endoftheinternet.com/";
diff --git a/tests/language/import/show_test.dart b/tests/language/import/show_test.dart
new file mode 100644
index 0000000..cb3a488
--- /dev/null
+++ b/tests/language/import/show_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, 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 import_show_test;
+
+import "package:expect/expect.dart";
+import "show_lib.dart" show theEnd;
+
+main() {
+ var foo = theEnd;
+ Expect.equals("http://www.endoftheinternet.com/", foo);
+}
diff --git a/tests/language/import/sub/sub.dart b/tests/language/import/sub/sub.dart
new file mode 100644
index 0000000..cd90247
--- /dev/null
+++ b/tests/language/import/sub/sub.dart
@@ -0,0 +1,8 @@
+library sub;
+
+import '../cyclic_test.dart';
+import 'package:expect/expect.dart';
+
+subMain() {
+ Expect.equals(42, value);
+}
diff --git a/tests/language/import/transitive_private_library_access_test.dart b/tests/language/import/transitive_private_library_access_test.dart
new file mode 100644
index 0000000..9dcdaed
--- /dev/null
+++ b/tests/language/import/transitive_private_library_access_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program to check that we can resolve unqualified identifiers
+
+// Import 'dart:typed_data' which internally imports 'dart:_internal'.
+import 'dart:typed_data';
+
+import 'package:expect/expect.dart';
+
+main() {
+ ClassID.GetID(4); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/initializing_formal/access_test.dart b/tests/language/initializing_formal/access_test.dart
new file mode 100644
index 0000000..79ce73f
--- /dev/null
+++ b/tests/language/initializing_formal/access_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+class C {
+ final int x;
+ final int y;
+
+ const C.constant(this.x) : y = x + 1;
+
+ C(this.x) : y = x + 1 {
+ int z = x + 2;
+ assert(z == y + 1);
+ }
+}
+
+main() {
+ C c = new C(2);
+ Expect.equals(c.x, 2);
+ Expect.equals(c.y, 3);
+ const C cc = const C.constant(4);
+ Expect.equals(cc.x, 4);
+ Expect.equals(cc.y, 5);
+}
diff --git a/tests/language/initializing_formal/capture_test.dart b/tests/language/initializing_formal/capture_test.dart
new file mode 100644
index 0000000..3fd2d2c
--- /dev/null
+++ b/tests/language/initializing_formal/capture_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+class A {
+ var x, y;
+ A(this.x) : y = (() => x);
+}
+
+main() {
+ A a = new A(2);
+ a.x = 3;
+ Expect.equals(a.x, 3);
+ Expect.equals(a.y(), 2);
+}
diff --git a/tests/language/initializing_formal/final_test.dart b/tests/language/initializing_formal/final_test.dart
new file mode 100644
index 0000000..d08f6d2
--- /dev/null
+++ b/tests/language/initializing_formal/final_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+class A {
+ var x, y;
+ // This should cause an error because `x` is final when accessed as an
+ // initializing formal.
+ A(this.x)
+ : y = (() {
+ /*@compile-error=unspecified*/ x = 3;
+ });
+}
+
+main() {}
diff --git a/tests/language/initializing_formal/promotion_test.dart b/tests/language/initializing_formal/promotion_test.dart
new file mode 100644
index 0000000..4820de2
--- /dev/null
+++ b/tests/language/initializing_formal/promotion_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+class B {}
+
+class A {
+ B? x, y;
+ // Promotion occurs for the initializing formal because C <: B.
+ A(this.x) : y = (x is C) ? x.x : x;
+}
+
+class C extends A implements B {
+ C(B? x) : super(x);
+}
+
+main() {
+ C c = new C(null);
+ C cc = new C(c);
+ Expect.equals(c.y, null);
+ Expect.equals(cc.y, null);
+}
diff --git a/tests/language/initializing_formal/scope_test.dart b/tests/language/initializing_formal/scope_test.dart
new file mode 100644
index 0000000..f75308f
--- /dev/null
+++ b/tests/language/initializing_formal/scope_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+// Duplicate definition checks for `this.x` will check the scopes associated
+// with the constructor, not all enclosing scopes; so this is not a conflict.
+var x;
+
+class A {
+ var x;
+ A(this.x) {
+ // In the body the field is in scope, not the initializing formal;
+ // so we can use the setter.
+ x += 1;
+ }
+}
+
+main() {
+ A a = new A(2);
+ Expect.equals(a.x, 3);
+}
diff --git a/tests/language/initializing_formal/type_annotation_runtime_test.dart b/tests/language/initializing_formal/type_annotation_runtime_test.dart
new file mode 100644
index 0000000..c09a0ff
--- /dev/null
+++ b/tests/language/initializing_formal/type_annotation_runtime_test.dart
@@ -0,0 +1,23 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing the static checks for type annotations on initializing formals.
+
+class C {
+ num a;
+ C.sameType(num this.a);
+ C.subType(int this.a);
+
+
+}
+
+main() {
+ new C.sameType(3.14);
+ new C.subType(42);
+
+
+}
diff --git a/tests/language/initializing_formal/type_annotation_test.dart b/tests/language/initializing_formal/type_annotation_test.dart
new file mode 100644
index 0000000..b15ad9a
--- /dev/null
+++ b/tests/language/initializing_formal/type_annotation_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Testing the static checks for type annotations on initializing formals.
+
+class C {
+ num a;
+ C.sameType(num this.a);
+ C.subType(int this.a);
+ C.superType(dynamic this.a);
+ // ^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_PARAMETER_DECLARATION
+ // ^
+ // [cfe] The type of parameter 'a', 'dynamic' is not a subtype of the corresponding field's type, 'num'.
+ C.unrelatedType(String this.a);
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_PARAMETER_DECLARATION
+ // ^^^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
+ // ^
+ // [cfe] The type of parameter 'a', 'String' is not a subtype of the corresponding field's type, 'num'.
+}
+
+main() {
+ new C.sameType(3.14);
+ new C.subType(42);
+ new C.superType([]);
+ new C.unrelatedType('String');
+}
diff --git a/tests/language/initializing_formal/type_test.dart b/tests/language/initializing_formal/type_test.dart
new file mode 100644
index 0000000..41a9f2a
--- /dev/null
+++ b/tests/language/initializing_formal/type_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ num x;
+ int y;
+ // x has type int in the initialization list, but num inside the constructor
+ // body.
+ A(int this.x) : y = x { // OK.
+ int z = x;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'num' can't be assigned to a variable of type 'int'.
+ }
+}
+
+main() {
+ A(0);
+}
diff --git a/tests/language/instance/call_wrong_argument_count_test.dart b/tests/language/instance/call_wrong_argument_count_test.dart
new file mode 100644
index 0000000..8f0c710
--- /dev/null
+++ b/tests/language/instance/call_wrong_argument_count_test.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.
+
+/// Test mismatch in argument counts.
+
+class Niederhorn {
+ int goodCall(int a, int b, int c) {
+ return a + b;
+ }
+}
+
+main() {
+ var niederhorn = Niederhorn();
+ niederhorn.goodCall(1, 2, 3);
+ niederhorn.goodCall(1, 2, 3, 4);
+ // ^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+ // [cfe] Too many positional arguments: 3 allowed, but 4 found.
+}
diff --git a/tests/language/instance/compound_assignment_operator_test.dart b/tests/language/instance/compound_assignment_operator_test.dart
new file mode 100644
index 0000000..b992acc
--- /dev/null
+++ b/tests/language/instance/compound_assignment_operator_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test correct instance compound assignment operator.
+
+import "package:expect/expect.dart";
+
+class A {
+ A() : f = 2 {}
+ var f;
+ operator [](index) => f;
+ operator []=(index, value) => f = value;
+
+ var _g = 0;
+ var gGetCount = 0;
+ var gSetCount = 0;
+ get g {
+ gGetCount++;
+ return _g;
+ }
+
+ set g(value) {
+ gSetCount++;
+ _g = value;
+ }
+}
+
+class B {
+ B()
+ : _a = new A(),
+ count = 0 {}
+ get a {
+ count++;
+ return _a;
+ }
+
+ var _a;
+ var count;
+}
+
+var globalA;
+var fooCounter = 0;
+foo() {
+ fooCounter++;
+ return globalA;
+}
+
+main() {
+ B b = new B();
+ Expect.equals(0, b.count);
+ Expect.equals(2, b.a.f);
+ Expect.equals(1, b.count);
+ var o = b.a;
+ Expect.equals(2, b.count);
+ b.a.f = 1;
+ Expect.equals(3, b.count);
+ Expect.equals(1, b._a.f);
+ b.a.f += 1;
+ Expect.equals(4, b.count);
+ Expect.equals(2, b._a.f);
+
+ b.count = 0;
+ b._a.f = 2;
+ Expect.equals(0, b.count);
+ Expect.equals(2, b.a[0]);
+ Expect.equals(1, b.count);
+ o = b.a;
+ Expect.equals(2, b.count);
+ b.a[0] = 1;
+ Expect.equals(3, b.count);
+ Expect.equals(1, b._a.f);
+ b.a[0] += 1;
+ Expect.equals(4, b.count);
+ Expect.equals(2, b._a.f);
+
+ b._a.g++;
+ Expect.equals(1, b._a.gGetCount);
+ Expect.equals(1, b._a.gSetCount);
+ Expect.equals(1, b._a._g);
+
+ globalA = b._a;
+ globalA.f = 0;
+ foo().f += 1;
+ Expect.equals(1, fooCounter);
+ Expect.equals(1, globalA.f);
+}
diff --git a/tests/language/instance/field_initializer_test.dart b/tests/language/instance/field_initializer_test.dart
new file mode 100644
index 0000000..1cb5c93
--- /dev/null
+++ b/tests/language/instance/field_initializer_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2011, 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:expect/expect.dart";
+
+class A {
+ int x = 1;
+ A() {}
+ A.reassign() : x = 2 {}
+ A.reassign2(this.x) {}
+}
+
+class B extends A {
+ B() : super() {}
+ B.reassign() : super.reassign() {}
+ B.reassign2() : super.reassign2(3) {}
+}
+
+class InstanceFieldInitializerTest {
+ static testMain() {
+ Expect.equals(1, new A().x);
+ Expect.equals(2, new A.reassign().x);
+ Expect.equals(3, new A.reassign2(3).x);
+
+ Expect.equals(1, new B().x);
+ Expect.equals(2, new B.reassign().x);
+ Expect.equals(3, new B.reassign2().x);
+ }
+}
+
+main() {
+ InstanceFieldInitializerTest.testMain();
+}
diff --git a/tests/language/instance/incr_deopt_test.dart b/tests/language/instance/incr_deopt_test.dart
new file mode 100644
index 0000000..d9424fd
--- /dev/null
+++ b/tests/language/instance/incr_deopt_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Check correct deoptimization of instance field increment.
+
+main() {
+ var a = new A();
+ var aa = new A();
+ for (int i = 0; i < 20; i++) {
+ a.Incr();
+ myIncr(aa);
+ conditionalIncr(false, a);
+ }
+ Expect.equals(20, a.f);
+ Expect.equals(20, aa.f);
+ a.f = 1.0;
+ // Deoptimize ++ part of instance increment.
+ a.Incr();
+ Expect.equals(2.0, a.f);
+ var b = new B();
+ // Deoptimize getfield part of instance increment.
+ myIncr(b);
+ Expect.equals(1.0, b.f);
+ // Deoptimize since no type feedback was collected.
+ var old = a.f;
+ conditionalIncr(true, a);
+ Expect.equals(old + 1, a.f);
+}
+
+myIncr(var a) {
+ a.f++;
+}
+
+conditionalIncr(var f, var a) {
+ if (f) {
+ a.f++;
+ }
+}
+
+class A {
+ A() : f = 0;
+ Incr() {
+ f++;
+ }
+
+ var f;
+}
+
+class B {
+ B() : f = 0;
+ var f;
+}
diff --git a/tests/language/instance/inline_test.dart b/tests/language/instance/inline_test.dart
new file mode 100644
index 0000000..0e58815
--- /dev/null
+++ b/tests/language/instance/inline_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+// Test inlining of assignments in parameter passing. If [StringScanner.charAt]
+// is inlined, the argument expression `++byteOffset` should not be duplicated.
+
+class StringScanner {
+ final String string;
+ int byteOffset = -1;
+
+ StringScanner(this.string);
+
+ int nextByte() => charAt(++byteOffset);
+
+ int charAt(index) => (string.length > index) ? string.codeUnitAt(index) : -1;
+}
+
+void main() {
+ var scanner = new StringScanner('az9');
+ Expect.equals(0x61, scanner.nextByte()); // Expect a.
+ Expect.equals(0x7A, scanner.nextByte()); // Expect z.
+ Expect.equals(0x39, scanner.nextByte()); // Expect 9.
+ Expect.equals(-1, scanner.nextByte());
+}
diff --git a/tests/language/instance/method2_test.dart b/tests/language/instance/method2_test.dart
new file mode 100644
index 0000000..de92967
--- /dev/null
+++ b/tests/language/instance/method2_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Check that we correctly flag the use of an instance method (as a closure)
+/// from a static method.
+
+class Goofy {
+ String instMethod() {
+ return "woof";
+ }
+
+ static Function bark() {
+ return instMethod;
+ // ^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INSTANCE_MEMBER_ACCESS_FROM_STATIC
+ // [cfe] Getter not found: 'instMethod'.
+ }
+}
+
+main() {
+ var s = Goofy.bark();
+}
diff --git a/tests/language/instance/method_test.dart b/tests/language/instance/method_test.dart
new file mode 100644
index 0000000..f2de913
--- /dev/null
+++ b/tests/language/instance/method_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Check that we correctly flag the use of an instance method from a static
+/// method.
+
+class Goofy {
+ String instMethod() {
+ return "woof";
+ }
+
+ static String bark() {
+ return instMethod();
+ // ^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INSTANCE_MEMBER_ACCESS_FROM_STATIC
+ // [cfe] Method not found: 'instMethod'.
+ }
+}
+
+main() {
+ Goofy.bark();
+}
diff --git a/tests/language/interceptor/interceptor2_test.dart b/tests/language/interceptor/interceptor2_test.dart
new file mode 100644
index 0000000..06260c8
--- /dev/null
+++ b/tests/language/interceptor/interceptor2_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+// Regression test for issue http://dartbug.com/6903: dart2js used to
+// not generate an interceptor forwarder when a getter call and a
+// method call on an intercepted method were both used.
+
+class A {
+ get iterator => () => 499;
+}
+
+main() {
+ var a = <dynamic>[
+ new A(),
+ [1, 1]
+ ];
+ Expect.equals(499, a[0].iterator());
+ Expect.equals(499, (a[0].iterator)());
+ for (var i in a[1]) {
+ Expect.equals(1, i);
+ }
+}
diff --git a/tests/language/interceptor/interceptor3_test.dart b/tests/language/interceptor/interceptor3_test.dart
new file mode 100644
index 0000000..b22b26d
--- /dev/null
+++ b/tests/language/interceptor/interceptor3_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+// Test that code motion in the presence of interceptors work in dart2js.
+
+main() {
+ var a = <dynamic>[2, '2'];
+ var b = a[1];
+ if (a[0] == 2 && b is String) {
+ Expect.isTrue(b.contains('2'));
+ } else {
+ b.isEven();
+ }
+}
diff --git a/tests/language/interceptor/interceptor4_test.dart b/tests/language/interceptor/interceptor4_test.dart
new file mode 100644
index 0000000..00bac28
--- /dev/null
+++ b/tests/language/interceptor/interceptor4_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+// Test that dart2js gets the right interceptor for an int.
+
+main() {
+ var a = [1];
+ var b = a[0];
+ Expect.equals('1', b.toString());
+ Expect.isTrue(b.isOdd);
+}
diff --git a/tests/language/interceptor/interceptor5_test.dart b/tests/language/interceptor/interceptor5_test.dart
new file mode 100644
index 0000000..41b76e9
--- /dev/null
+++ b/tests/language/interceptor/interceptor5_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+get X => [() => 123];
+
+main() {
+ Expect.equals(123, X.last());
+}
diff --git a/tests/language/interceptor/interceptor7_test.dart b/tests/language/interceptor/interceptor7_test.dart
new file mode 100644
index 0000000..7e88bcd
--- /dev/null
+++ b/tests/language/interceptor/interceptor7_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js uses the right interceptor when call a method on
+// something that has type number.
+
+import 'package:expect/expect.dart';
+
+var array = <dynamic>[];
+
+main() {
+ array.add(false);
+ dynamic x = array[0] ? 1.5 : 2;
+ Expect.isTrue(x.isEven);
+}
diff --git a/tests/language/interceptor/interceptor8_test.dart b/tests/language/interceptor/interceptor8_test.dart
new file mode 100644
index 0000000..0890124
--- /dev/null
+++ b/tests/language/interceptor/interceptor8_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js whose codegen used to not consider a double
+// could be instantiated when doing int / int.
+
+var a = [5, 2];
+
+main() {
+ print(a[0] / a[1]);
+}
diff --git a/tests/language/interceptor/interceptor9_test.dart b/tests/language/interceptor/interceptor9_test.dart
new file mode 100644
index 0000000..07525a5
--- /dev/null
+++ b/tests/language/interceptor/interceptor9_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for dart2js whose codegen in some cases did not take is
+// tests into account when computing the set of classes for interceptors.
+// See http://dartbug.com/17325
+
+import "package:expect/expect.dart";
+import "dart:typed_data";
+
+confuse(x, [y = null]) => new DateTime.now().day == 42 ? y : x;
+
+boom() {
+ var x = confuse(new Uint8List(22), "");
+ Expect.isTrue(x is Uint8List);
+ x.startsWith("a");
+ x.endsWith("u");
+}
+
+main() {
+ try {
+ var f;
+ if (confuse(true)) {
+ // prevent inlining
+ f = boom;
+ }
+ f();
+ } catch (e) {
+ if (e is ExpectException) throw e;
+ }
+}
diff --git a/tests/language/interceptor/interceptor_test.dart b/tests/language/interceptor/interceptor_test.dart
new file mode 100644
index 0000000..7faf174
--- /dev/null
+++ b/tests/language/interceptor/interceptor_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+// Test that interceptors (that is, methods in classes implemented as
+// JavaScript primitives) in dart2js work.
+
+class A {
+ codeUnitAt(a) => a;
+}
+
+main() {
+ var res = <dynamic>[[], 1, 'foo', new A()];
+ Expect.throws(() => res[0].codeUnitAt(1));
+ Expect.throws(() => (res[0].codeUnitAt)(1));
+
+ Expect.throws(() => res[1].codeUnitAt(1));
+ Expect.throws(() => (res[1].codeUnitAt)(1));
+
+ Expect.equals(111, res[2].codeUnitAt(1));
+ Expect.equals(111, (res[2].codeUnitAt)(1));
+ Expect.throws(() => res[2].codeUnitAt(1, 4));
+ Expect.throws(() => res[2].codeUnitAt());
+ Expect.throws(() => (res[2].codeUnitAt)(1, 4));
+ Expect.throws(() => (res[2].codeUnitAt)());
+
+ Expect.equals(1, res[3].codeUnitAt(1));
+ Expect.equals(1, (res[3].codeUnitAt)(1));
+ Expect.throws(() => res[3].codeUnitAt(1, 4));
+ Expect.throws(() => res[3].codeUnitAt());
+ Expect.throws(() => (res[3].codeUnitAt)(1, 4));
+ Expect.throws(() => (res[3].codeUnitAt)());
+}
diff --git a/tests/language/interface/constants_test.dart b/tests/language/interface/constants_test.dart
new file mode 100644
index 0000000..5654066
--- /dev/null
+++ b/tests/language/interface/constants_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+abstract class Constants {
+ static const int FIVE = 5;
+}
+
+class InterfaceConstantsTest {
+ InterfaceConstantsTest() {}
+
+ static void testMain() {
+ Expect.equals(5, Constants.FIVE);
+ }
+}
+
+main() {
+ InterfaceConstantsTest.testMain();
+}
diff --git a/tests/language/interface/cycle_test.dart b/tests/language/interface/cycle_test.dart
new file mode 100644
index 0000000..0e44708
--- /dev/null
+++ b/tests/language/interface/cycle_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2012, 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.
+// Check fail because of cycles in super interface relationship.
+
+class C implements B {}
+
+class A implements B {}
+
+class B
+ implements A // //# 01: compile-time error
+ implements A // //# 02: compile-time error
+{}
+
+main() {
+ new C(); // //# 01: continued
+ new List<C>(); // //# 02: continued
+}
diff --git a/tests/language/interface/duplicate_implements_test.dart b/tests/language/interface/duplicate_implements_test.dart
new file mode 100644
index 0000000..41c10fa
--- /dev/null
+++ b/tests/language/interface/duplicate_implements_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, 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.
+// Check that duplicate types in implements/extends list are
+// compile-time errors.
+
+abstract class I {}
+
+abstract class J {}
+
+abstract class K<T> {}
+
+class X implements I, J, I { } // //# 01: compile-time error
+class X implements J, I, K<int>, K<int> { } // //# 02: compile-time error
+
+abstract class Z implements I, J, J { } // //# 03: compile-time error
+abstract class Z implements K<int>, K<int> { } // //# 04: compile-time error
+
+main() {
+ X x = new X(); // //# 01: continued
+ X x = new X(); // //# 02: continued
+ Z z = new Z(); // //# 03: continued
+ Z z = new Z(); // //# 04: continued
+}
diff --git a/tests/language/interface/duplicate_interface_implements_runtime_test.dart b/tests/language/interface/duplicate_interface_implements_runtime_test.dart
new file mode 100644
index 0000000..aced31d
--- /dev/null
+++ b/tests/language/interface/duplicate_interface_implements_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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 "duplicate_interface_lib.dart" as alib;
+import "duplicate_interface_lib.dart" show InterfA;
+
+// Expect error since InterfA and alib.InterfA refer to the same interface.
+class Foo implements InterfA
+
+{}
+
+main() {
+ new Foo();
+}
diff --git a/tests/language/interface/duplicate_interface_implements_test.dart b/tests/language/interface/duplicate_interface_implements_test.dart
new file mode 100644
index 0000000..4564aad
--- /dev/null
+++ b/tests/language/interface/duplicate_interface_implements_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, 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 "duplicate_interface_lib.dart" as alib;
+import "duplicate_interface_lib.dart" show InterfA;
+
+// Expect error since InterfA and alib.InterfA refer to the same interface.
+class Foo implements InterfA
+ , alib.InterfA
+ //^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_REPEATED
+{}
+
+main() {
+ new Foo();
+}
diff --git a/tests/language/interface/duplicate_interface_lib.dart b/tests/language/interface/duplicate_interface_lib.dart
new file mode 100644
index 0000000..b369b3a
--- /dev/null
+++ b/tests/language/interface/duplicate_interface_lib.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, 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.
+// Check fail because of cycles in super class relationship.
+
+library Interface_Lib;
+
+class InterfA {}
+
+class InterfB {}
diff --git a/tests/language/interface/duplicate_interface_test.dart b/tests/language/interface/duplicate_interface_test.dart
new file mode 100644
index 0000000..d957be9
--- /dev/null
+++ b/tests/language/interface/duplicate_interface_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, 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.
+// Check fail because of cycles in super class relationship.
+
+library duplicateInterfaceTest;
+
+import 'package:expect/expect.dart';
+import "duplicate_interface_lib.dart" as alib;
+
+class InterfB {}
+
+// Ok since InterfB and alib.InterfB are not the same interface
+class Foo implements InterfB, alib.InterfB {}
+
+main() {
+ Expect.isTrue(new Foo() is InterfB);
+ Expect.isTrue(new Foo() is alib.InterfB);
+}
diff --git a/tests/language/interface/implements_futureor_runtime_test.dart b/tests/language/interface/implements_futureor_runtime_test.dart
new file mode 100644
index 0000000..257056b
--- /dev/null
+++ b/tests/language/interface/implements_futureor_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+class A<T>
+
+{}
+
+void main() {
+ A a = new A();
+}
diff --git a/tests/language/interface/implements_futureor_test.dart b/tests/language/interface/implements_futureor_test.dart
new file mode 100644
index 0000000..1ec6779
--- /dev/null
+++ b/tests/language/interface/implements_futureor_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+class A<T> implements FutureOr<T> {}
+// ^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DISALLOWED_CLASS
+// ^
+// [cfe] The type 'FutureOr' can't be used in an 'implements' clause.
+
+void main() {
+ A a = new A();
+}
diff --git a/tests/language/interface/inherit_field_test.dart b/tests/language/interface/inherit_field_test.dart
new file mode 100644
index 0000000..fa43fb9
--- /dev/null
+++ b/tests/language/interface/inherit_field_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that it is legal to override a field with a field in an interface.
+
+abstract class IA {
+ final int foo;
+ IA(this.foo);
+}
+
+abstract class IB implements IA {
+ final int foo;
+ IB(this.foo);
+}
+
+class B implements IB {
+ int _f = 123;
+ int get foo => _f;
+}
+
+main() {
+ IB b = new B();
+ print('b.foo = ${b.foo}');
+}
diff --git a/tests/language/interface/injection1_runtime_test.dart b/tests/language/interface/injection1_runtime_test.dart
new file mode 100644
index 0000000..ab438b4
--- /dev/null
+++ b/tests/language/interface/injection1_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The removed language feature "interface injection" is now a syntax error.
+
+import "package:expect/expect.dart";
+
+abstract class S { }
+abstract class I { }
+
+
+class C implements I { }
+
+main() {
+ Expect.isFalse(new C() is S);
+}
diff --git a/tests/language/interface/injection1_test.dart b/tests/language/interface/injection1_test.dart
new file mode 100644
index 0000000..9a3faf4
--- /dev/null
+++ b/tests/language/interface/injection1_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The removed language feature "interface injection" is now a syntax error.
+
+import "package:expect/expect.dart";
+
+abstract class S { }
+abstract class I { }
+abstract class I implements S;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'I' is already declared in this scope.
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_BODY
+// [cfe] A class declaration must have a body, even if it is empty.
+// ^
+// [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
+// [cfe] Unexpected token ';'.
+
+class C implements I { }
+// ^
+// [cfe] 'I' isn't a type.
+
+main() {
+ Expect.isFalse(new C() is S);
+}
diff --git a/tests/language/interface/injection2_runtime_test.dart b/tests/language/interface/injection2_runtime_test.dart
new file mode 100644
index 0000000..a8a6788
--- /dev/null
+++ b/tests/language/interface/injection2_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The removed language feature "interface injection" is now a syntax error.
+
+import "package:expect/expect.dart";
+
+abstract class S { }
+class C { }
+
+
+main() {
+ Expect.isFalse(new C() is S);
+}
diff --git a/tests/language/interface/injection2_test.dart b/tests/language/interface/injection2_test.dart
new file mode 100644
index 0000000..e49d5bd
--- /dev/null
+++ b/tests/language/interface/injection2_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The removed language feature "interface injection" is now a syntax error.
+
+import "package:expect/expect.dart";
+
+abstract class S { }
+class C { }
+class C implements S;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'C' is already declared in this scope.
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_BODY
+// [cfe] A class declaration must have a body, even if it is empty.
+// ^
+// [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
+// [cfe] Unexpected token ';'.
+
+main() {
+ Expect.isFalse(new C() is S);
+ // ^
+ // [cfe] Method not found: 'C'.
+}
diff --git a/tests/language/interface/interface2_test.dart b/tests/language/interface/interface2_test.dart
new file mode 100644
index 0000000..7b8282c
--- /dev/null
+++ b/tests/language/interface/interface2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A class must implement a known interface.
+
+class Interface2NegativeTest implements BooHoo {}
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_NON_CLASS
+// [cfe] Type 'BooHoo' not found.
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+
+main() {
+ Interface2NegativeTest();
+}
diff --git a/tests/language/interface/interface_test.dart b/tests/language/interface/interface_test.dart
new file mode 100644
index 0000000..b05e0a6
--- /dev/null
+++ b/tests/language/interface/interface_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing Interfaces.
+
+abstract class Ai {
+ int foo();
+}
+
+abstract class Bi implements Ai {
+ factory Bi() = InterfaceTest;
+ // ^
+ // [cfe] Factory redirects to class 'InterfaceTest', which is abstract and can't be instantiated.
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR
+}
+
+abstract class Simple implements Ai {}
+
+abstract class Aai {}
+
+abstract class Abi {}
+
+abstract class Bar {}
+
+abstract class Foo implements Bar {}
+
+abstract class Baz implements Bar, Foo {}
+
+abstract class InterfaceTest implements Ai, Aai, Abi, Baz, Bi {
+ var f;
+
+ InterfaceTest() {}
+ int foo() {
+ return 1;
+ }
+
+ // intentionally unimplemented methods
+ beta(); // Abstract.
+ String beta1(); // Abstract.
+ String beta2(double d); // Abstract.
+}
+
+main() {
+ new Bi();
+}
diff --git a/tests/language/interface/runtime_test.dart b/tests/language/interface/runtime_test.dart
new file mode 100644
index 0000000..b789fe7
--- /dev/null
+++ b/tests/language/interface/runtime_test.dart
@@ -0,0 +1,45 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing Interfaces.
+
+abstract class Ai {
+ int foo();
+}
+
+abstract class Bi implements Ai {
+
+}
+
+abstract class Simple implements Ai {}
+
+abstract class Aai {}
+
+abstract class Abi {}
+
+abstract class Bar {}
+
+abstract class Foo implements Bar {}
+
+abstract class Baz implements Bar, Foo {}
+
+abstract class InterfaceTest implements Ai, Aai, Abi, Baz, Bi {
+ var f;
+
+ InterfaceTest() {}
+ int foo() {
+ return 1;
+ }
+
+ // intentionally unimplemented methods
+ beta(); // Abstract.
+ String beta1(); // Abstract.
+ String beta2(double d); // Abstract.
+}
+
+main() {
+
+}
diff --git a/tests/language/interface/static_method_test.dart b/tests/language/interface/static_method_test.dart
new file mode 100644
index 0000000..b07e7b9
--- /dev/null
+++ b/tests/language/interface/static_method_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+abstract class A {
+ static void foo();
+ // ^
+ // [analyzer] SYNTACTIC_ERROR.MISSING_FUNCTION_BODY
+ // [cfe] Expected a function body or '=>'.
+}
+
+main() {
+ A();
+//^
+// [analyzer] STATIC_WARNING.INSTANTIATE_ABSTRACT_CLASS
+// [cfe] The class 'A' is abstract and can't be instantiated.
+}
diff --git a/tests/language/label/label3_runtime_1_test.dart b/tests/language/label/label3_runtime_1_test.dart
new file mode 100644
index 0000000..76da501
--- /dev/null
+++ b/tests/language/label/label3_runtime_1_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L: while (false) {
+ if (true) break L;
+ }
+ // Illegal: L is out of scope.
+
+}
diff --git a/tests/language/label/label3_runtime_test.dart b/tests/language/label/label3_runtime_test.dart
new file mode 100644
index 0000000..afcaad7
--- /dev/null
+++ b/tests/language/label/label3_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L: while (false) {
+
+ }
+ // Illegal: L is out of scope.
+
+}
diff --git a/tests/language/label/label3_test.dart b/tests/language/label/label3_test.dart
new file mode 100644
index 0000000..cdea8e4
--- /dev/null
+++ b/tests/language/label/label3_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L: while (false) {
+ if (true) break L;
+ }
+ // Illegal: L is out of scope.
+ continue L;
+//^^^^^^^^
+// [analyzer] SYNTACTIC_ERROR.CONTINUE_OUTSIDE_OF_LOOP
+// [cfe] A continue statement can't be used outside of a loop or switch statement.
+// ^
+// [analyzer] COMPILE_TIME_ERROR.LABEL_UNDEFINED
+// [cfe] Can't find label 'L'.
+}
diff --git a/tests/language/label/label5_runtime_test.dart b/tests/language/label/label5_runtime_test.dart
new file mode 100644
index 0000000..fd934f0
--- /dev/null
+++ b/tests/language/label/label5_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ var L = 33;
+ while (false) {
+ // Illegal: L is not a label.
+
+ }
+}
diff --git a/tests/language/label/label5_test.dart b/tests/language/label/label5_test.dart
new file mode 100644
index 0000000..9856809
--- /dev/null
+++ b/tests/language/label/label5_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ var L = 33;
+ while (false) {
+ // Illegal: L is not a label.
+ if (true) break L;
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.LABEL_UNDEFINED
+ // [cfe] Can't break to 'L'.
+ }
+}
diff --git a/tests/language/label/label6_runtime_1_test.dart b/tests/language/label/label6_runtime_1_test.dart
new file mode 100644
index 0000000..effe712
--- /dev/null
+++ b/tests/language/label/label6_runtime_1_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L:
+ while (false) {
+ break;
+
+ void innerfunc() {
+ // Illegal: jump target is outside of function
+
+ }
+
+ innerfunc();
+ }
+}
diff --git a/tests/language/label/label6_runtime_2_test.dart b/tests/language/label/label6_runtime_2_test.dart
new file mode 100644
index 0000000..732c430
--- /dev/null
+++ b/tests/language/label/label6_runtime_2_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L:
+ while (false) {
+
+ break L;
+ void innerfunc() {
+ // Illegal: jump target is outside of function
+
+ }
+
+ innerfunc();
+ }
+}
diff --git a/tests/language/label/label6_runtime_test.dart b/tests/language/label/label6_runtime_test.dart
new file mode 100644
index 0000000..e240a78
--- /dev/null
+++ b/tests/language/label/label6_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L:
+ while (false) {
+
+
+ void innerfunc() {
+ // Illegal: jump target is outside of function
+
+ }
+
+ innerfunc();
+ }
+}
diff --git a/tests/language/label/label6_test.dart b/tests/language/label/label6_test.dart
new file mode 100644
index 0000000..5219b01
--- /dev/null
+++ b/tests/language/label/label6_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ L:
+ while (false) {
+ break;
+ break L;
+ void innerfunc() {
+ // Illegal: jump target is outside of function
+ if (true) break L;
+ // ^
+ // [cfe] Can't break to 'L' in a different function.
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.LABEL_IN_OUTER_SCOPE
+ }
+
+ innerfunc();
+ }
+}
diff --git a/tests/language/label/label8_runtime_test.dart b/tests/language/label/label8_runtime_test.dart
new file mode 100644
index 0000000..4573cbc
--- /dev/null
+++ b/tests/language/label/label8_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ int i = 0;
+ // Grammar doesn't allow label on block for switch statement.
+ switch(i)
+
+ {
+ case 111:
+ while (false) {
+
+ }
+ i++;
+ }
+}
diff --git a/tests/language/label/label8_test.dart b/tests/language/label/label8_test.dart
new file mode 100644
index 0000000..e17e3b1
--- /dev/null
+++ b/tests/language/label/label8_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ int i = 0;
+ // Grammar doesn't allow label on block for switch statement.
+ switch(i)
+ // ^
+ // [analyzer] SYNTACTIC_ERROR.EXPECTED_BODY
+ // [cfe] A switch statement must have a body, even if it is empty.
+ L:
+ {
+ case 111:
+// ^^^^
+// [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+// [cfe] Expected ';' after this.
+// ^^^^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected an identifier, but got 'case'.
+// ^^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+// [cfe] Getter not found: 'case'.
+// ^^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_STATEMENT
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ';' after this.
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ';' after this.
+// ^
+// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+// [cfe] Expected an identifier, but got ':'.
+// ^
+// [analyzer] SYNTACTIC_ERROR.UNEXPECTED_TOKEN
+// [cfe] Unexpected token ':'.
+ while (false) {
+ break L;
+ }
+ i++;
+ }
+}
diff --git a/tests/language/label/label_test.dart b/tests/language/label/label_test.dart
new file mode 100644
index 0000000..74f3cd7
--- /dev/null
+++ b/tests/language/label/label_test.dart
@@ -0,0 +1,352 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program to test check that we can parse labels.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ static int ticks = 0;
+
+ // Helper function to prevent endless loops in case labels or
+ // break/continue is broken.
+ static doAgain() {
+ ++ticks;
+ if (ticks > 300) {
+ // obfuscating man's assert(false)
+ Expect.equals(true, false);
+ }
+ return true;
+ }
+
+ static test1() {
+ var i = 1;
+ while (doAgain()) {
+ if (i > 0) break;
+ return 0;
+ }
+ return 111;
+ }
+
+ static test2() {
+ // Make sure we break out to default label.
+ var i = 1;
+ L:
+ while (doAgain()) {
+ // unused label
+ if (i > 0) break;
+ return 0;
+ }
+ return 111;
+ }
+
+ static test3() {
+ // Make sure we break out of outer loop.
+ var i = 1;
+ L:
+ while (doAgain()) {
+ while (doAgain()) {
+ if (i > 0) break L;
+ return 0;
+ }
+ return 1;
+ }
+ return 111;
+ }
+
+ static test4() {
+ // Make sure we break out of inner loop.
+ var i = 100;
+ L:
+ while (doAgain()) {
+ // unused label
+ while (doAgain()) {
+ if (i > 0) break;
+ return 0;
+ }
+ return 111;
+ }
+ return 1;
+ }
+
+ static test5() {
+ // Make sure we jump to loop condition.
+ var i = 10;
+ while (i > 0) {
+ i--;
+ if (true) continue; // without the if the following return is dead code.
+ return 0;
+ }
+ return 111;
+ }
+
+ static test6() {
+ // Make sure we jump to loop condition.
+ L:
+ for (int i = 10; i > 0; i--) {
+ // unreferenced label, should warn
+ if (true) continue; // without the if the following return is dead code.
+ return 0;
+ }
+ // Make sure this L does not conflict with previous L.
+ var k = 20;
+ L:
+ while (doAgain()) {
+ L0:
+ while (doAgain()) break L; // unreferenced label L0, should warn
+ return 1;
+ }
+ return 111;
+ }
+
+ static test7() {
+ // Just weird stuff.
+ var i = 10;
+ L:
+ do {
+ L:
+ while (doAgain()) {
+ if (true) break L; // without the if the following line is dead code.
+ continue L;
+ }
+ i = 0;
+ continue L;
+ } while (i == 10 && doAgain());
+ return 111;
+ }
+
+ static test8() {
+ L:
+ while (false) {
+ var L = 33; // OK, shouldn't collide with label.
+ if (true) break L;
+ }
+ return 111;
+ }
+
+ static test9() {
+ var i = 111;
+ L1:
+ if (i == 0) {
+ // unreferenced label, should warn
+ return 0;
+ }
+
+ L2:
+ while (i == 0) {
+ // unreferenced label, should warn
+ return 0;
+ }
+
+ L3: // useless label, should warn
+ return i;
+ }
+
+ // Labels should be allowed on block/if/for/switch/while/do stmts.
+ static test10() {
+ int i = 111;
+ // block
+ while (doAgain()) {
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ }
+ break;
+ }
+ Expect.equals(111, i);
+
+ while (doAgain()) {
+ L:
+ if (doAgain()) {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ }
+ break;
+ }
+ Expect.equals(111, i);
+
+ while (doAgain()) {
+ L:
+ for (; doAgain();) {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ }
+ break;
+ }
+ Expect.equals(111, i);
+
+ L:
+ for (i in [111]) {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+
+ L:
+ for (var j in [111]) {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+
+ while (doAgain()) {
+ L:
+ switch (i) {
+ case 111:
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ default:
+ i--;
+ }
+ break;
+ }
+ Expect.equals(111, i);
+
+ while (doAgain()) {
+ L:
+ do {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ } while (doAgain());
+ break;
+ }
+ Expect.equals(111, i);
+
+ while (doAgain()) {
+ L:
+ try {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ } finally {}
+ break;
+ }
+ Expect.equals(111, i);
+
+ return i;
+ }
+
+ static test11() {
+ // Kind of odd, but is valid and shouldn't be flagged as useless either.
+ L:
+ break L;
+ return 111;
+ }
+
+ static test12() {
+ int i = 111;
+
+ // label the inner block on compound stmts
+ if (true)
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ }
+ Expect.equals(111, i);
+
+ // loop will execute each time, but won't execute code below the break
+ var forCount = 0;
+ for (forCount = 0; forCount < 2; forCount++)
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+ Expect.equals(forCount, 2);
+
+ for (i in [111])
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+
+ for (var j in [111])
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+
+ if (false) {} else
+ L:
+ {
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ }
+ Expect.equals(111, i);
+
+ int whileCount = 0;
+ while (whileCount < 2)
+ L:
+ {
+ whileCount++;
+ while (doAgain()) {
+ break L;
+ }
+ i--;
+ break;
+ }
+ Expect.equals(111, i);
+ Expect.equals(2, whileCount);
+
+ return i;
+ }
+}
+
+class LabelTest {
+ static testMain() {
+ Expect.equals(111, Helper.test1());
+ Expect.equals(111, Helper.test2());
+ Expect.equals(111, Helper.test3());
+ Expect.equals(111, Helper.test4());
+ Expect.equals(111, Helper.test5());
+ Expect.equals(111, Helper.test6());
+ Expect.equals(111, Helper.test7());
+ Expect.equals(111, Helper.test8());
+ Expect.equals(111, Helper.test9());
+ Expect.equals(111, Helper.test10());
+ Expect.equals(111, Helper.test11());
+ Expect.equals(111, Helper.test12());
+ }
+}
+
+main() {
+ LabelTest.testMain();
+}
diff --git a/tests/language/nnbd/is_type_test/null_is_type_in_legacy_lib_test.dart b/tests/language/nnbd/is_type_test/null_is_type_in_legacy_lib_test.dart
index 00c2449..ddf79bd 100644
--- a/tests/language/nnbd/is_type_test/null_is_type_in_legacy_lib_test.dart
+++ b/tests/language/nnbd/is_type_test/null_is_type_in_legacy_lib_test.dart
@@ -5,6 +5,9 @@
// Opt out of Null Safety:
// @dart = 2.6
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
import 'package:expect/expect.dart';
import 'null_safe_library.dart';
diff --git a/tests/language/nnbd/is_type_test/null_is_type_in_null_safe_lib_test.dart b/tests/language/nnbd/is_type_test/null_is_type_in_null_safe_lib_test.dart
index 6a2acd5..3721c69 100644
--- a/tests/language/nnbd/is_type_test/null_is_type_in_null_safe_lib_test.dart
+++ b/tests/language/nnbd/is_type_test/null_is_type_in_null_safe_lib_test.dart
@@ -2,6 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
import 'package:expect/expect.dart';
import 'legacy_library.dart';
diff --git a/tests/language/nnbd/normalization/generic_function_type_object_normalization_test.dart b/tests/language/nnbd/normalization/generic_function_type_object_normalization_test.dart
new file mode 100644
index 0000000..4cb9036d
--- /dev/null
+++ b/tests/language/nnbd/normalization/generic_function_type_object_normalization_test.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'type_builder.dart';
+
+// Tests for runtime type object normalization.
+
+// Check that two objects have equal runtime types,
+// compared in any order.
+void checkTypeEquals2(Object? a, Object? b) {
+ checkEquals2(a.runtimeType, b.runtimeType);
+}
+
+// Check that two objects have unequal runtime types,
+// compared in any order.
+void checkTypeNotEquals2(Object? a, Object? b) {
+ checkNotEquals2(a.runtimeType, b.runtimeType);
+}
+
+// Check that three objects have equal runtime types,
+// compared in combination and any order.
+void checkTypeEquals3(Object? a, Object? b, Object? c) {
+ checkTypeEquals2(a, b);
+ checkTypeEquals2(a, c);
+ checkTypeEquals2(b, c);
+}
+
+// Check that three objects have unequal runtime types,
+// compared in combination and any order.
+void checkTypeNotEquals3(Object? a, Object? b, Object? c) {
+ checkTypeNotEquals2(a, b);
+ checkTypeNotEquals2(a, c);
+ checkTypeNotEquals2(b, c);
+}
+
+// Tests of generic function types.
+
+class SimpleBoundTests<T> {
+ // These are equal if `T` is equivalent to a top type or Object
+ T f1<S extends FutureOr<T>>() => throw "Unused";
+ T f2<R extends T>() => throw "Unused";
+
+ // These are equal if `T` is equivalent to Never or Null
+ T g1<S extends FutureOr<T>?>() => throw "Unused";
+ T g2<R extends Future<T>?>() => throw "Unused";
+
+ // These are equal if `T` is nullable
+ T h1<S extends FutureOr<T>?>() => throw "Unused";
+ T h2<R extends FutureOr<T>>() => throw "Unused";
+
+ // If `T` is a top type, check that the appropriate
+ // equalities and disequalities hold.
+ static void checkAtTopType<T>() {
+ var a = SimpleBoundTests<T>();
+ checkTypeEquals2(a.f1, a.f2);
+ checkTypeNotEquals2(a.g1, a.g2);
+ checkTypeEquals2(a.h1, a.h2);
+ }
+
+ // Check the top type related equalites and inequalities
+ // at various top types.
+ static void checkTopTypes() {
+ checkAtTopType<Object?>();
+ checkAtTopType<void>();
+ checkAtTopType<dynamic>();
+ checkAtTopType<FutureOr<Object?>>();
+ }
+
+ // Check that the types of the methods above are equal or not at
+ // a bottom type
+ static void checkAtBottomType<T>() {
+ var a = SimpleBoundTests<T>();
+ checkTypeNotEquals2(a.f1, a.f2);
+ checkTypeEquals2(a.g1, a.g2);
+ if (null is T) {
+ checkTypeEquals2(a.h1, a.h2);
+ } else {
+ checkTypeNotEquals2(a.h1, a.h2);
+ }
+ }
+
+ // Check that the types of the methods above are equal or not at
+ // the bottom types
+ static void checkBottomTypes() {
+ checkAtBottomType<Null>();
+ checkAtBottomType<Never>();
+ checkAtBottomType<Never?>();
+ }
+
+ // Check that the methods above have different types given
+ // a non-top, non-nullable type.
+ static void checkAtNonNullableType<T extends Object>() {
+ var a = SimpleBoundTests<T>();
+ checkTypeNotEquals2(a.f1, a.f2);
+ checkTypeNotEquals2(a.g1, a.g2);
+ checkTypeNotEquals2(a.h1, a.h2);
+ }
+
+ // Check that the methods above have different types for
+ // several non-top non-nullable types.
+ static void checkNonNullableTypes() {
+ checkAtNonNullableType<int>();
+ checkAtNonNullableType<String>();
+ checkAtNonNullableType<Iterable<int>>();
+ checkAtNonNullableType<Future<Object>>();
+ }
+
+ // Check that the methods above are equal or not given
+ // a non-top nullable type.
+ static void checkAtNullableType<T>() {
+ var a = SimpleBoundTests<T>();
+ checkTypeNotEquals2(a.f1, a.f2);
+ checkTypeNotEquals2(a.g1, a.g2);
+ checkTypeEquals2(a.h1, a.h2);
+ }
+
+ // Check that the methods above are equal or not for
+ // several non-top nullable types.
+ static void checkNullableTypes() {
+ checkAtNullableType<int?>();
+ checkAtNullableType<String?>();
+ checkAtNullableType<Iterable<int>?>();
+ checkAtNullableType<Future<Object>?>();
+ }
+
+ static void check() {
+ checkTopTypes();
+ checkBottomTypes();
+ checkNonNullableTypes();
+ checkNullableTypes();
+ }
+}
+
+class NeverTests<T> {
+ T f1<S extends T>(T x) => throw "Unused";
+ S f2<S extends T>(Object? x) => throw "Unused";
+ Never f3<S extends T>(Object? x) => throw "Unused";
+
+ R g1<S extends T, R extends S>(List<S> x) => throw "Unused";
+ Never g2<S extends T, R extends S>(List<Never> x) => throw "Unused";
+
+ FutureOr<R> h1<S extends T, R extends S>(S? x) => throw "Unused";
+ Future<Never> h2<S extends T, R extends S>(Null x) => throw "Unused";
+
+ // void Function<S0 extends FutureOr<R>, S1 extends R, S2 extends R?>()
+ // TODO(41952) restore the proper type above when nullable bounds work
+ // correctly in the CFE.
+ Function i1<R>() =>
+ <T0 extends FutureOr<R>, T1 extends R, T2 extends R?>() {};
+
+ void Function<S0 extends Future<Never>, S1 extends Never, S2 extends Null>()
+ i2<R>() =>
+ <R0 extends Future<Never>, R1 extends Never, R2 extends Null>() {};
+}
+
+void neverBoundTests() {
+ {
+ var o = NeverTests<Never>();
+ checkTypeEquals3(o.f1, o.f2, o.f3);
+ checkTypeEquals2(o.g1, o.g2);
+ checkTypeEquals2(o.h1, o.h2);
+ checkTypeEquals2(o.i1<Never>(), o.i2<Never>());
+ checkTypeNotEquals2(o.i1<Null>(), o.i2<Null>());
+ }
+ {
+ var o = NeverTests<Null>();
+ checkTypeNotEquals3(o.f1, o.f2, o.f3);
+ checkTypeNotEquals2(o.g1, o.g2);
+ checkTypeNotEquals2(o.h1, o.h2);
+ checkTypeNotEquals2(o.i1<Never>(), o.i2<Never>());
+ checkTypeNotEquals2(o.i1<Null>(), o.i2<Null>());
+ }
+}
+
+void fBoundedTests() {
+ void f1<T extends FutureOr<T>>() {}
+ void f2<S extends FutureOr<S>>() {}
+
+ checkTypeEquals2(f1, f2);
+
+ void g1<T extends List<S>, S extends T>() {}
+ void g2<T0 extends List<S0>, S0 extends T0>() {}
+
+ checkTypeEquals2(g1, g2);
+
+ void h1<T extends FutureOr<T?>?>() {}
+ void h2<S extends FutureOr<S?>>() {}
+
+ checkTypeEquals2(h1, h2);
+}
+
+void main() {
+ SimpleBoundTests.check();
+ neverBoundTests();
+ fBoundedTests();
+}
diff --git a/tests/language/nnbd/normalization/type_builder.dart b/tests/language/nnbd/normalization/type_builder.dart
new file mode 100644
index 0000000..c858dc5
--- /dev/null
+++ b/tests/language/nnbd/normalization/type_builder.dart
@@ -0,0 +1,170 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+// This defines a set of higher order combinators for building objects
+// of type Type at runtime. A key constraint behind this design is that
+// the structure of the Type objects is constructed at runtime by
+// applying type constructors (e.g. `FutureOr`) to types provided via
+// instantiation of generic methods. This ensures that normalization
+// is performed at runtime (or during optimization in the compiler) rather
+// than as a simple static rewrite in the front end.
+
+// A TypeBuilder is a parametric type builder that allows composing together
+// different builders at runtime. The intuition is that a
+// TypeBuilder represents a latent computation of a type `T`.
+// TypeBuilders can be composed together to produce computations
+// which compute more complex types. For example, we define below
+// `FutureOr` combinator which given a TypeBuilder for a type `T`
+// produces a TypeBuilder for the type `FutureOr<T>`.
+// The type represented by a TypeBuilder can be reified into a runtime
+// type object by calling the TypeBuilder with a generic function which
+// uses its type parameter to produce a runtime type object as desired.
+// So for example, calling the TypeBuilder representing the type `int`
+// with `<T>() => T` produces the runtime Type representation of `int`.
+typedef TypeBuilder = Type Function(Type Function<T>());
+
+// Given a type `T`, produce a TypeBuilder which builds `T`
+TypeBuilder $Primitive<T>() => (build) => build<T>();
+
+// Given a TypeBuilder for a type `T`, return a TypeBuilder for `FutureOr<T>`
+TypeBuilder $FutureOr(TypeBuilder of) =>
+ (build) => of(<T>() => build<FutureOr<T>>());
+
+// Given a TypeBuilder for a type `T`, return a TypeBuilder for `T?`
+TypeBuilder $OrNull(TypeBuilder of) => (build) => of(<T>() => build<T?>());
+
+// Given a TypeBuilder for a type `T`, return a TypeBuilder for `List<T>`
+TypeBuilder $List(TypeBuilder of) => (build) => of(<T>() => build<List<T>>());
+
+// Given a TypeBuilder for a type `T`, return a TypeBuilder for `Future<T>`
+TypeBuilder $Future(TypeBuilder of) =>
+ (build) => of(<T>() => build<Future<T>>());
+
+// Given a TypeBuilder for a type `From` and a TypeBuilder for a type `To`,
+// return a TypeBuilder for `To Function(From)`
+TypeBuilder $Function1(TypeBuilder from, TypeBuilder to) =>
+ (build) => from(<From>() => to(<To>() => build<To Function(From)>()));
+
+// Given a TypeBuilder for a type `From` and a TypeBuilder for a type `To`,
+// return a TypeBuilder for `To Function({From a})`
+TypeBuilder $FunctionOptionalNamedA(TypeBuilder from, TypeBuilder to) =>
+ (build) => from(<From>() => to(<To>() => build<To Function({From a})>()));
+
+// Given a TypeBuilder for a type `From` and a TypeBuilder for a type `To`,
+// return a TypeBuilder for `To Function({From b})`
+TypeBuilder $FunctionOptionalNamedB(TypeBuilder from, TypeBuilder to) =>
+ (build) => from(<From>() => to(<To>() => build<To Function({From b})>()));
+
+// Given a TypeBuilder for a type `From` and a TypeBuilder for a type `To`,
+// return a TypeBuilder for `To Function({required From a})`
+TypeBuilder $FunctionRequiredNamedA(TypeBuilder from, TypeBuilder to) =>
+ (build) =>
+ from(<From>() => to(<To>() => build<To Function({required From a})>()));
+
+// Define some primitive TypeBuilder objects
+TypeBuilder $int = $Primitive<int>();
+TypeBuilder $Object = $Primitive<Object>();
+TypeBuilder $ObjectQ = $OrNull($Object);
+TypeBuilder $dynamic = $Primitive<dynamic>();
+TypeBuilder $void = $Primitive<void>();
+TypeBuilder $Never = $Primitive<Never>();
+TypeBuilder $Null = $Primitive<Null>();
+
+// A helper class for testing equality of objects produced
+// by the .runtimeType method.
+class Rep<T> {}
+
+TypeBuilder $Rep(TypeBuilder of) => (build) => of(<R>() => build<Rep<R>>());
+
+// A helper class for testing equality of objects produced
+// by implicit calls to noSuchMethod.
+class NSM {
+ Type noSuchMethod(i) => i.typeArguments.first;
+}
+
+// Given a TypeBuilder for `T`, reify `T` directly to a Type object
+Type typeObjectOf(TypeBuilder build) => build(<T>() => T);
+
+// Given a TypeBuilder for a type `T`, create an instance o of `Rep<T>`
+// and return the result of calling o.runtimeType
+Type runtimeTypeOfRepOf(TypeBuilder build) =>
+ build(<T>() => Rep<T>().runtimeType);
+
+// Given a TypeBuilder for a type `T`, cause an invocation NSM.noSuchMethod
+// `T` as a runtime type object in the `typeArguments` list of the Invocation
+// object passed to the handler, and return that runtime type object as the
+// result.
+Type noSuchMethodTypeOf(TypeBuilder build) =>
+ build(<T>() => (NSM() as dynamic).method<T>());
+
+// Check that two objects are equal to themselves
+void checkReflexivity2(Object? a, Object? b) {
+ Expect.equals(a, a);
+ Expect.equals(b, b);
+}
+
+// Check that two objects are equal
+// compared in any order.
+void checkEquals2(Object? a, Object? b) {
+ checkReflexivity2(a, b);
+ Expect.equals(a, b);
+ Expect.equals(b, a);
+}
+
+// Given a list of objects, check that each is
+// equal to every element of the list.
+void checkAllEquals(List<Object?> elements) {
+ var count = elements.length;
+ for (var element1 in elements) {
+ for (var element2 in elements) {
+ Expect.equals(element1, element2);
+ Expect.equals(element2, element1);
+ }
+ }
+}
+
+// Check that two objects are unequal
+// compared in any order.
+void checkNotEquals2(Object? a, Object? b) {
+ checkReflexivity2(a, b);
+ Expect.notEquals(a, b);
+ Expect.notEquals(b, a);
+}
+
+// Given two TypeBuilder objects, check that reifying the type
+// represented by the two builders produces equal types, whether
+// that reification happens via a direct reification; via reification
+// as a generic type on a class; or via reification as a type argument to
+// a noSuchMethod handler invocation.
+void checkTypeEqualities(TypeBuilder a, TypeBuilder b) {
+ checkAllEquals([
+ typeObjectOf(a),
+ typeObjectOf(b),
+ noSuchMethodTypeOf(a),
+ noSuchMethodTypeOf(b)
+ ]);
+
+ checkAllEquals([
+ typeObjectOf($Rep(a)),
+ typeObjectOf($Rep(b)),
+ noSuchMethodTypeOf($Rep(a)),
+ noSuchMethodTypeOf($Rep(b)),
+ runtimeTypeOfRepOf(a),
+ runtimeTypeOfRepOf(b)
+ ]);
+}
+
+// Given two TypeBuilder objects, check that reifying the type
+// represented by the two builders produces unequal types, whether
+// that reification happens via a direct reification; via reification
+// as a generic type on a class; or via reification as a type argument to
+// a noSuchMethod handler invocation.
+void checkTypeInequalities(TypeBuilder a, TypeBuilder b) {
+ checkNotEquals2(typeObjectOf(a), typeObjectOf(b));
+ checkNotEquals2(runtimeTypeOfRepOf(a), runtimeTypeOfRepOf(b));
+ checkNotEquals2(noSuchMethodTypeOf(a), noSuchMethodTypeOf(b));
+}
diff --git a/tests/language/nnbd/normalization/type_object_normalization_test.dart b/tests/language/nnbd/normalization/type_object_normalization_test.dart
new file mode 100644
index 0000000..9d3ebbe8
--- /dev/null
+++ b/tests/language/nnbd/normalization/type_object_normalization_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'type_builder.dart';
+
+// Tests for runtime type object normalization.
+
+// Tests of non-generic function types.
+void simpleTypeTests() {
+ // Different top types are not runtime equal
+ checkTypeInequalities($ObjectQ, $dynamic);
+ checkTypeInequalities($ObjectQ, $void);
+ checkTypeInequalities($dynamic, $void);
+
+ // FutureOr^n of top type is that top type
+ checkTypeEqualities($FutureOr($FutureOr($ObjectQ)), $ObjectQ);
+ checkTypeEqualities($FutureOr($FutureOr($dynamic)), $dynamic);
+ checkTypeEqualities($FutureOr($FutureOr($void)), $void);
+
+ // FutureOr^n of top type is not a different top type
+ checkTypeInequalities($FutureOr($FutureOr($ObjectQ)), $dynamic);
+ checkTypeInequalities($FutureOr($FutureOr($ObjectQ)), $void);
+ checkTypeInequalities($FutureOr($FutureOr($dynamic)), $void);
+
+ // FutureOr of Object is Object
+ checkTypeEqualities($FutureOr($Object), $Object);
+ checkTypeEqualities($FutureOr($FutureOr($Object)), $Object);
+
+ // FutureOr of Object is not a top type
+ checkTypeInequalities($FutureOr($Object), $ObjectQ);
+ checkTypeInequalities($FutureOr($FutureOr($Object)), $dynamic);
+ checkTypeInequalities($FutureOr($FutureOr($FutureOr($Object))), $void);
+
+ // FutureOr of Never is Future<Never>
+ checkTypeEqualities($FutureOr($Never), $Future($Never));
+
+ // FutureOr of Null is Future<Null>?
+ checkTypeEqualities($FutureOr($Null), $OrNull($Future($Null)));
+
+ // FutureOr of Null is not Future<Null>
+ checkTypeInequalities($FutureOr($Null), $Future($Null));
+
+ // Top type or Null is that top type
+ checkTypeEqualities($OrNull($ObjectQ), $ObjectQ);
+ checkTypeEqualities($OrNull($dynamic), $dynamic);
+ checkTypeEqualities($OrNull($void), $void);
+ checkTypeEqualities($OrNull($FutureOr($ObjectQ)), $ObjectQ);
+
+ // Never is not Null
+ checkTypeInequalities($Never, $Null);
+
+ // Never? is Null
+ checkTypeEqualities($OrNull($Never), $Null);
+
+ // Null? is Null
+ checkTypeEqualities($OrNull($Null), $Null);
+
+ // FutureOr<T>? is FutureOr<T> if T is nullable
+ checkTypeEqualities(
+ $OrNull($FutureOr($OrNull($int))), $FutureOr($OrNull($int)));
+
+ // FutureOr<T>? is not FutureOr<T> if T is not nullable
+ checkTypeInequalities($OrNull($FutureOr($int)), $FutureOr($int));
+
+ // FutureOr<T>? is not FutureOr<T?> if T is not nullable
+ checkTypeInequalities($OrNull($FutureOr($int)), $FutureOr($OrNull($int)));
+
+ // T?? is T?
+ checkTypeEqualities($OrNull($OrNull($OrNull($int))), $OrNull($int));
+
+ // Top?? is Top
+ checkTypeEqualities($OrNull($OrNull($dynamic)), $dynamic);
+
+ // List<T> is List<R> if T is R
+ checkTypeEqualities($List($FutureOr($Never)), $List($Future($Never)));
+ checkTypeEqualities($List($OrNull($Never)), $List($Null));
+ checkTypeEqualities($List($FutureOr($Object)), $List($Object));
+
+ // B Function(A) is D Function(C) if A is C and B is D
+ checkTypeEqualities(
+ $Function1(
+ $OrNull($FutureOr($OrNull($Null))), $FutureOr($FutureOr($Object))),
+ $Function1($OrNull($Future($Null)), $Object));
+
+ // B Function({A a}) is D Function({C a}) if A is C and B is D
+ checkTypeEqualities(
+ $FunctionOptionalNamedA(
+ $OrNull($FutureOr($OrNull($Null))), $FutureOr($FutureOr($Object))),
+ $FunctionOptionalNamedA($OrNull($Future($Null)), $Object));
+
+ // B Function({A a}) is not D Function({C b}) even if A is C and B is D
+ checkTypeInequalities(
+ $FunctionOptionalNamedA(
+ $OrNull($FutureOr($OrNull($Null))), $FutureOr($FutureOr($Object))),
+ $FunctionOptionalNamedB($OrNull($Future($Null)), $Object));
+
+ // B Function({required A a}) is D Function({required C a}) if A is C and B is D
+ checkTypeEqualities(
+ $FunctionRequiredNamedA(
+ $OrNull($FutureOr($OrNull($Null))), $FutureOr($FutureOr($Object))),
+ $FunctionRequiredNamedA($OrNull($Future($Null)), $Object));
+
+ // B Function({required A a}) is not D Function({C a}) even if A is C and B is D
+ checkTypeInequalities(
+ $FunctionRequiredNamedA(
+ $OrNull($FutureOr($OrNull($Null))), $FutureOr($FutureOr($Object))),
+ $FunctionOptionalNamedA($OrNull($Future($Null)), $Object));
+}
+
+void main() {
+ simpleTypeTests();
+}
diff --git a/tests/language/nnbd/normalization/type_object_normalization_weak_test.dart b/tests/language/nnbd/normalization/type_object_normalization_weak_test.dart
new file mode 100644
index 0000000..ddd9b60
--- /dev/null
+++ b/tests/language/nnbd/normalization/type_object_normalization_weak_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.7
+
+// Requirements=nnbd-weak
+
+import 'dart:async';
+import 'type_builder.dart';
+
+// Tests for runtime type object normalization with legacy types
+
+// TypeBuilder for legacy `*` types. Note that the type parameter `S` may
+// be a non-legacy type, but by passing it on as an argument to `build` here
+// in a legacy library, a legacy `*` marker is added.
+TypeBuilder $Star(TypeBuilder of) => (build) => of(<S>() => build<S>());
+
+// These tests check that normalization handles `*` types correctly
+void legacyTypeNormalizationTests() {
+ // FutureOr<Object*> is Object*
+ checkTypeEqualities($FutureOr($Star($Object)), $Star($Object));
+
+ // Never*? is Null
+ checkTypeEqualities($OrNull($Star($Never)), $Null);
+
+ // FutureOr<R>* is FutureOr<R> if R is nullable
+ checkTypeEqualities(
+ $Star($FutureOr($OrNull($int))), $FutureOr($OrNull($int)));
+
+ // R*? is R?
+ checkTypeEqualities($OrNull($Star($int)), $OrNull($int));
+
+ // Top* is Top
+ checkTypeEqualities($Star($ObjectQ), $ObjectQ);
+ checkTypeEqualities($Star($dynamic), $dynamic);
+ checkTypeEqualities($Star($void), $void);
+
+ // Null* is Null
+ checkTypeEqualities($Star($Null), $Null);
+
+ // R?* is R?
+ checkTypeEqualities($Star($OrNull($int)), $OrNull($int));
+
+ // R*** is R*
+ checkTypeEqualities($Star($Star($Star($int))), $Star($int));
+}
+
+// These tests check that equality ignores `*` types in weak mode, but
+// does not equate Null and Never and does not ignore required.
+void weakModeTests() {
+ // Object* is Object
+ checkTypeEqualities($Star($Object), $Object);
+
+ // int* is int
+ checkTypeEqualities($Star($int), $int);
+
+ // Null* is Null
+ checkTypeEqualities($Star($Null), $Null);
+
+ // Never* is Never
+ checkTypeEqualities($Star($Never), $Never);
+
+ // List<T> is List<S> if T is S
+ checkTypeEqualities($List($Star($Object)), $List($Object));
+
+ // List<T> is List<S> if T is S
+ checkTypeEqualities($List($FutureOr($Star($Object))), $List($Object));
+
+ // Never is not Null, even in weak mode
+ checkTypeInequalities($Never, $Null);
+
+ // Never* is not Null, even in weak mode
+ checkTypeInequalities($Star($Never), $Null);
+
+ // Object* is not Object?, even in weak mode
+ checkTypeInequalities($Star($Object), $ObjectQ);
+
+ // B Function(A) is D Function(C) if A is C and B is D
+ checkTypeEqualities($Function1($Star($Object), $OrNull($Star($int))),
+ $Function1($Object, $OrNull($int)));
+
+ // B Function({A a}) is D Function({C a}) if A is C and B is D
+ checkTypeEqualities(
+ $FunctionOptionalNamedA($Star($Object), $OrNull($Star($int))),
+ $FunctionOptionalNamedA($Object, $OrNull($int)));
+
+ // B Function({required A a}) is D Function({required C a}) if A is C and B is D
+ checkTypeEqualities(
+ $FunctionRequiredNamedA($Star($Object), $OrNull($Star($int))),
+ $FunctionRequiredNamedA($Object, $OrNull($int)));
+
+ // B Function({required A a}) is not D Function({C a}) even if A is C and B is D
+ checkTypeInequalities($FunctionRequiredNamedA($Object, $OrNull($int)),
+ $FunctionOptionalNamedA($Object, $OrNull($int)));
+}
+
+void main() {
+ legacyTypeNormalizationTests();
+ weakModeTests();
+}
diff --git a/tests/language/nnbd/static_errors/export_legacy_symbol_test.dart b/tests/language/nnbd/static_errors/export_legacy_symbol_test.dart
index c28b2ed..25ea45c 100644
--- a/tests/language/nnbd/static_errors/export_legacy_symbol_test.dart
+++ b/tests/language/nnbd/static_errors/export_legacy_symbol_test.dart
@@ -2,6 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
// SharedOptions=--enable-experiment=non-nullable
import 'export_legacy_symbol_opted_out_library.dart';
diff --git a/tests/language/nnbd/subtyping/function_type_bounds_test.dart b/tests/language/nnbd/subtyping/function_type_bounds_test.dart
index fca16f8..1a0c6a4 100644
--- a/tests/language/nnbd/subtyping/function_type_bounds_test.dart
+++ b/tests/language/nnbd/subtyping/function_type_bounds_test.dart
@@ -2,7 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Requirements=nnbd
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
import 'package:expect/expect.dart';
diff --git a/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart b/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart
deleted file mode 100644
index 5044d65..0000000
--- a/tests/language/nnbd/subtyping/mixed_bottom_type_strong_test.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart = 2.6
-
-// Requirements=nnbd-strong
-
-import 'package:expect/expect.dart';
-import 'mixed_bottom_type_lib.dart';
-
-main() {
- // The subtype check `void Function(String) <: void Function(Null)` should be
- // false in strong mode semantics since `Null </: String`.
- Expect.isFalse(stringFunction is void Function(Null));
-}
diff --git a/tests/language/nnbd/subtyping/non_nullable_instantiation_with_nullable_test.dart b/tests/language/nnbd/subtyping/non_nullable_instantiation_with_nullable_test.dart
index 7dc4d3f..07845ba 100644
--- a/tests/language/nnbd/subtyping/non_nullable_instantiation_with_nullable_test.dart
+++ b/tests/language/nnbd/subtyping/non_nullable_instantiation_with_nullable_test.dart
@@ -4,7 +4,8 @@
// @dart = 2.6
-// Requirements=nnbd
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
import 'package:expect/expect.dart';
diff --git a/tests/language/nnbd/subtyping/recursive_legacy_type_bounds_test.dart b/tests/language/nnbd/subtyping/recursive_legacy_type_bounds_test.dart
index 6cf9b28..d735c81 100644
--- a/tests/language/nnbd/subtyping/recursive_legacy_type_bounds_test.dart
+++ b/tests/language/nnbd/subtyping/recursive_legacy_type_bounds_test.dart
@@ -2,6 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
import 'package:expect/expect.dart';
import 'recursive_legacy_type_bounds_lib.dart';
diff --git a/tests/language/nnbd/type_equality/function_type_equality_nnbd_lib.dart b/tests/language/nnbd/type_equality/function_type_equality_nnbd_lib.dart
new file mode 100644
index 0000000..f0b0410
--- /dev/null
+++ b/tests/language/nnbd/type_equality/function_type_equality_nnbd_lib.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+void fn() => null;
+void fn2() => null;
+int voidToInt() => 42;
+int voidToInt2() => 42;
+int? voidToNullableInt() => 42;
+int? voidToNullableInt2() => 42;
+void positionalIntToVoid(int i) => null;
+void positionalNullableIntToVoid(int? i) => null;
+void positionalNullableIntToVoid2(int? i) => null;
+void optionalIntToVoid([int i = 0]) => null;
+void optionalIntToVoid2([int i = 0]) => null;
+void optionalNullableIntToVoid([int? i]) => null;
+void optionalNullableIntToVoid2([int? i]) => null;
+void namedIntToVoid({int i = 0}) => null;
+void namedIntToVoid2({int i = 0}) => null;
+void namedNullableIntToVoid({int? i}) => null;
+void namedNullableIntToVoid2({int? i}) => null;
+void requiredIntToVoid({required int i}) => null;
+void requiredIntToVoid2({required int i}) => null;
+void requiredNullableIntToVoid({required int? i}) => null;
+void requiredNullableIntToVoid2({required int? i}) => null;
+void gn(bool b, [int i = 0]) => null;
+void hn(bool b, {int i = 0}) => null;
diff --git a/tests/language/nnbd/type_equality/function_type_equality_test.dart b/tests/language/nnbd/type_equality/function_type_equality_test.dart
index 10fffac..16357eb 100644
--- a/tests/language/nnbd/type_equality/function_type_equality_test.dart
+++ b/tests/language/nnbd/type_equality/function_type_equality_test.dart
@@ -4,31 +4,7 @@
import 'package:expect/expect.dart';
-import 'function_type_equality_legacy_lib.dart' as legacy;
-
-void fn() => null;
-void fn2() => null;
-int voidToInt() => 42;
-int voidToInt2() => 42;
-int? voidToNullableInt() => 42;
-int? voidToNullableInt2() => 42;
-void positionalIntToVoid(int i) => null;
-void positionalNullableIntToVoid(int? i) => null;
-void positionalNullableIntToVoid2(int? i) => null;
-void optionalIntToVoid([int i = 0]) => null;
-void optionalIntToVoid2([int i = 0]) => null;
-void optionalNullableIntToVoid([int? i]) => null;
-void optionalNullableIntToVoid2([int? i]) => null;
-void namedIntToVoid({int i = 0}) => null;
-void namedIntToVoid2({int i = 0}) => null;
-void namedNullableIntToVoid({int? i}) => null;
-void namedNullableIntToVoid2({int? i}) => null;
-void requiredIntToVoid({required int i}) => null;
-void requiredIntToVoid2({required int i}) => null;
-void requiredNullableIntToVoid({required int? i}) => null;
-void requiredNullableIntToVoid2({required int? i}) => null;
-void gn(bool b, [int i = 0]) => null;
-void hn(bool b, {int i = 0}) => null;
+import 'function_type_equality_nnbd_lib.dart';
main() {
// Same functions with different names.
@@ -47,28 +23,6 @@
Expect.equals(requiredNullableIntToVoid.runtimeType,
requiredNullableIntToVoid2.runtimeType);
- // Same signatures but one is from a legacy library.
- Expect.equals(fn.runtimeType, legacy.fn.runtimeType);
- Expect.equals(voidToInt.runtimeType, legacy.voidToInt.runtimeType);
- Expect.equals(
- positionalIntToVoid.runtimeType, legacy.positionalIntToVoid.runtimeType);
- Expect.equals(
- optionalIntToVoid.runtimeType, legacy.optionalIntToVoid.runtimeType);
- Expect.equals(namedIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
- Expect.equals(gn.runtimeType, legacy.gn.runtimeType);
- Expect.equals(hn.runtimeType, legacy.hn.runtimeType);
-
- // Nullable types are not equal to legacy types.
- Expect.notEquals(positionalNullableIntToVoid.runtimeType,
- legacy.positionalIntToVoid.runtimeType);
- Expect.notEquals(optionalNullableIntToVoid.runtimeType,
- legacy.optionalIntToVoid.runtimeType);
- Expect.notEquals(
- namedNullableIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
- Expect.notEquals(voidToNullableInt.runtimeType, legacy.voidToInt.runtimeType);
-
// Required named arguments are not equal to named arguments.
Expect.notEquals(requiredIntToVoid.runtimeType, namedIntToVoid.runtimeType);
- Expect.notEquals(
- requiredIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
}
diff --git a/tests/language/nnbd/type_equality/function_type_equality_weak_test.dart b/tests/language/nnbd/type_equality/function_type_equality_weak_test.dart
new file mode 100644
index 0000000..b750f1b
--- /dev/null
+++ b/tests/language/nnbd/type_equality/function_type_equality_weak_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+
+import 'function_type_equality_nnbd_lib.dart';
+import 'function_type_equality_legacy_lib.dart' as legacy;
+
+main() {
+ // Same signatures but one is from a legacy library.
+ Expect.equals(fn.runtimeType, legacy.fn.runtimeType);
+ Expect.equals(voidToInt.runtimeType, legacy.voidToInt.runtimeType);
+ Expect.equals(
+ positionalIntToVoid.runtimeType, legacy.positionalIntToVoid.runtimeType);
+ Expect.equals(
+ optionalIntToVoid.runtimeType, legacy.optionalIntToVoid.runtimeType);
+ Expect.equals(namedIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
+ Expect.equals(gn.runtimeType, legacy.gn.runtimeType);
+ Expect.equals(hn.runtimeType, legacy.hn.runtimeType);
+
+ // Nullable types are not equal to legacy types.
+ Expect.notEquals(positionalNullableIntToVoid.runtimeType,
+ legacy.positionalIntToVoid.runtimeType);
+ Expect.notEquals(optionalNullableIntToVoid.runtimeType,
+ legacy.optionalIntToVoid.runtimeType);
+ Expect.notEquals(
+ namedNullableIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
+ Expect.notEquals(voidToNullableInt.runtimeType, legacy.voidToInt.runtimeType);
+
+ // Required named arguments are not equal to named arguments.
+ Expect.notEquals(
+ requiredIntToVoid.runtimeType, legacy.namedIntToVoid.runtimeType);
+}
diff --git a/tests/language/nnbd/type_equality/futureOr_normalization_legacy_test.dart b/tests/language/nnbd/type_equality/futureOr_normalization_legacy_test.dart
index e159821..caf9611 100644
--- a/tests/language/nnbd/type_equality/futureOr_normalization_legacy_test.dart
+++ b/tests/language/nnbd/type_equality/futureOr_normalization_legacy_test.dart
@@ -5,6 +5,9 @@
// Opt out of Null Safety:
// @dart = 2.6
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
import 'dart:async';
import 'package:expect/expect.dart';
diff --git a/tests/language/nnbd/type_equality/futureOr_normalization_test.dart b/tests/language/nnbd/type_equality/futureOr_normalization_test.dart
index 5592e73..0c0e3a0 100644
--- a/tests/language/nnbd/type_equality/futureOr_normalization_test.dart
+++ b/tests/language/nnbd/type_equality/futureOr_normalization_test.dart
@@ -3,10 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+// Requirements=nnbd
+
import 'package:expect/expect.dart';
import 'futureOr_normalization_null_safe_lib.dart';
-import 'futureOr_normalization_legacy_lib.dart' as legacy;
class A {}
@@ -42,7 +43,4 @@
extractType<Embed<FutureOr<int?>>>(), embedNullableFutureOrType<int?>());
Expect.equals(
extractType<Embed<FutureOr<A?>>>(), embedNullableFutureOrType<A?>());
-
- // Object* == FutureOr<Object*>
- Expect.equals(legacy.object, legacy.nonNullableFutureOrOfLegacyObject());
}
diff --git a/tests/language/nnbd/type_equality/futureOr_normalization_weak_test.dart b/tests/language/nnbd/type_equality/futureOr_normalization_weak_test.dart
new file mode 100644
index 0000000..f94ec37
--- /dev/null
+++ b/tests/language/nnbd/type_equality/futureOr_normalization_weak_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
+
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+
+import 'futureOr_normalization_legacy_lib.dart' as legacy;
+import 'futureOr_normalization_null_safe_lib.dart';
+
+main() {
+ // Object* == FutureOr<Object*>
+ Expect.equals(legacy.object, legacy.nonNullableFutureOrOfLegacyObject());
+}
diff --git a/tests/language/nnbd/type_equality/generic_function_type_equality_null_safe_lib.dart b/tests/language/nnbd/type_equality/generic_function_type_equality_null_safe_lib.dart
index bda1426..16abcb9 100644
--- a/tests/language/nnbd/type_equality/generic_function_type_equality_null_safe_lib.dart
+++ b/tests/language/nnbd/type_equality/generic_function_type_equality_null_safe_lib.dart
@@ -5,3 +5,33 @@
class B {}
class C extends B {}
+
+void fn<T>() => null;
+void fn2<R>() => null;
+T voidToT<T>() => null as T;
+S voidToS<S>() => null as S;
+void positionalTToVoid<T>(T i) => null;
+void positionalSToVoid<S>(S i) => null;
+void positionalNullableTToVoid<T>(T? i) => null;
+void positionalNullableSToVoid<S>(S? i) => null;
+void optionalTToVoid<T>([List<T> i = const <Never>[]]) => null;
+void optionalSToVoid<S>([List<S> i = const <Never>[]]) => null;
+void optionalNullableTToVoid<T>([T? i]) => null;
+void optionalNullableSToVoid<S>([S? i]) => null;
+void namedTToVoid<T>({List<T> i = const <Never>[]}) => null;
+void namedSToVoid<S>({List<S> i = const <Never>[]}) => null;
+void namedNullableTToVoid<T>({T? i}) => null;
+void namedNullableSToVoid<S>({S? i}) => null;
+void requiredTToVoid<T>({required T i}) => null;
+void requiredSToVoid<S>({required S i}) => null;
+void requiredNullableTToVoid<T>({required T? i}) => null;
+void requiredNullableSToVoid<S>({required S? i}) => null;
+
+void positionalTToVoidWithBound<T extends B>(T i) => null;
+void optionalTToVoidWithBound<T extends B>([List<T> i = const <Never>[]]) =>
+ null;
+void namedTToVoidWithBound<T extends B>({List<T> i = const <Never>[]}) => null;
+
+class A<T extends B> {
+ void fn(T i) => null;
+}
diff --git a/tests/language/nnbd/type_equality/generic_function_type_equality_test.dart b/tests/language/nnbd/type_equality/generic_function_type_equality_test.dart
index bd18b9a..22da2f8 100644
--- a/tests/language/nnbd/type_equality/generic_function_type_equality_test.dart
+++ b/tests/language/nnbd/type_equality/generic_function_type_equality_test.dart
@@ -2,40 +2,11 @@
// 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.
+// Requirements=nnbd
+
import 'package:expect/expect.dart';
-import 'generic_function_type_equality_legacy_lib.dart' as legacy;
import 'generic_function_type_equality_null_safe_lib.dart';
-void fn<T>() => null;
-void fn2<R>() => null;
-T voidToT<T>() => null as T;
-S voidToS<S>() => null as S;
-void positionalTToVoid<T>(T i) => null;
-void positionalSToVoid<S>(S i) => null;
-void positionalNullableTToVoid<T>(T? i) => null;
-void positionalNullableSToVoid<S>(S? i) => null;
-void optionalTToVoid<T>([List<T> i = const <Never>[]]) => null;
-void optionalSToVoid<S>([List<S> i = const <Never>[]]) => null;
-void optionalNullableTToVoid<T>([T? i]) => null;
-void optionalNullableSToVoid<S>([S? i]) => null;
-void namedTToVoid<T>({List<T> i = const <Never>[]}) => null;
-void namedSToVoid<S>({List<S> i = const <Never>[]}) => null;
-void namedNullableTToVoid<T>({T? i}) => null;
-void namedNullableSToVoid<S>({S? i}) => null;
-void requiredTToVoid<T>({required T i}) => null;
-void requiredSToVoid<S>({required S i}) => null;
-void requiredNullableTToVoid<T>({required T? i}) => null;
-void requiredNullableSToVoid<S>({required S? i}) => null;
-
-void positionalTToVoidWithBound<T extends B>(T i) => null;
-void optionalTToVoidWithBound<T extends B>([List<T> i = const <Never>[]]) =>
- null;
-void namedTToVoidWithBound<T extends B>({List<T> i = const <Never>[]}) => null;
-
-class A<T extends B> {
- void fn(T i) => null;
-}
-
main() {
// Same functions with different names.
Expect.equals(fn.runtimeType, fn2.runtimeType);
@@ -53,33 +24,8 @@
Expect.equals(
requiredNullableTToVoid.runtimeType, requiredNullableSToVoid.runtimeType);
- // Default type bounds are not equal. T extends Object? vs T extends Object*
- Expect.notEquals(fn.runtimeType, legacy.fn.runtimeType);
- Expect.notEquals(voidToT.runtimeType, legacy.voidToR.runtimeType);
- Expect.notEquals(
- positionalTToVoid.runtimeType, legacy.positionalRToVoid.runtimeType);
- Expect.notEquals(
- optionalTToVoid.runtimeType, legacy.optionalRToVoid.runtimeType);
- Expect.notEquals(namedTToVoid.runtimeType, legacy.namedRToVoid.runtimeType);
-
- // Type arguments in methods tear-offs from null safe libraries become Object?
- // and Object* from legacy libraries and are not equal.
- Expect.notEquals(A().fn.runtimeType, legacy.A().fn.runtimeType);
- Expect.notEquals(A().fn.runtimeType, legacy.rawAFnTearoff.runtimeType);
- Expect.notEquals(A<C>().fn.runtimeType, legacy.A<C>().fn.runtimeType);
-
- // Same signatures but one is from a legacy library.
- Expect.equals(positionalTToVoidWithBound.runtimeType,
- legacy.positionalTToVoidWithBound.runtimeType);
- Expect.equals(optionalTToVoidWithBound.runtimeType,
- legacy.optionalTToVoidWithBound.runtimeType);
- Expect.equals(namedTToVoidWithBound.runtimeType,
- legacy.namedTToVoidWithBound.runtimeType);
-
// Required named arguments are not equal to named arguments.
Expect.notEquals(namedTToVoid.runtimeType, requiredTToVoid.runtimeType);
Expect.notEquals(
namedNullableTToVoid.runtimeType, requiredNullableTToVoid.runtimeType);
- Expect.notEquals(
- requiredTToVoid.runtimeType, legacy.namedRToVoid.runtimeType);
}
diff --git a/tests/language/nnbd/type_equality/generic_function_type_equality_weak_test.dart b/tests/language/nnbd/type_equality/generic_function_type_equality_weak_test.dart
new file mode 100644
index 0000000..6f9007e
--- /dev/null
+++ b/tests/language/nnbd/type_equality/generic_function_type_equality_weak_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
+import 'package:expect/expect.dart';
+import 'generic_function_type_equality_legacy_lib.dart' as legacy;
+import 'generic_function_type_equality_null_safe_lib.dart';
+
+main() {
+ // Default type bounds are not equal. T extends Object? vs T extends Object*
+ Expect.notEquals(fn.runtimeType, legacy.fn.runtimeType);
+ Expect.notEquals(voidToT.runtimeType, legacy.voidToR.runtimeType);
+ Expect.notEquals(
+ positionalTToVoid.runtimeType, legacy.positionalRToVoid.runtimeType);
+ Expect.notEquals(
+ optionalTToVoid.runtimeType, legacy.optionalRToVoid.runtimeType);
+ Expect.notEquals(namedTToVoid.runtimeType, legacy.namedRToVoid.runtimeType);
+
+ // Type arguments in methods tear-offs from null safe libraries become Object?
+ // and Object* from legacy libraries and are not equal.
+ Expect.notEquals(A().fn.runtimeType, legacy.A().fn.runtimeType);
+ Expect.notEquals(A().fn.runtimeType, legacy.rawAFnTearoff.runtimeType);
+ Expect.notEquals(A<C>().fn.runtimeType, legacy.A<C>().fn.runtimeType);
+
+ // Same signatures but one is from a legacy library.
+ Expect.equals(positionalTToVoidWithBound.runtimeType,
+ legacy.positionalTToVoidWithBound.runtimeType);
+ Expect.equals(optionalTToVoidWithBound.runtimeType,
+ legacy.optionalTToVoidWithBound.runtimeType);
+ Expect.equals(namedTToVoidWithBound.runtimeType,
+ legacy.namedTToVoidWithBound.runtimeType);
+
+ // Required named arguments are not equal to named arguments.
+ Expect.notEquals(
+ requiredTToVoid.runtimeType, legacy.namedRToVoid.runtimeType);
+}
diff --git a/tests/language/nnbd/type_object/equality_test.dart b/tests/language/nnbd/type_object/equality_test.dart
index fdbf783..e96d8fb 100644
--- a/tests/language/nnbd/type_object/equality_test.dart
+++ b/tests/language/nnbd/type_object/equality_test.dart
@@ -2,9 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import "package:expect/expect.dart";
+// Requirements=nnbd
-import "legacy_library.dart";
+import "package:expect/expect.dart";
class A {}
@@ -33,13 +33,6 @@
Expect.isTrue(type<int?>() == type<int?>());
Expect.isFalse(type<int?>() == type<int>());
- Expect.isFalse(type<int?>() == legacyType<int>());
Expect.isFalse(type<int>() == type<int?>());
Expect.isTrue(type<int>() == type<int>());
- Expect.isTrue(type<int>() == legacyType<int>());
- Expect.isFalse(legacyType<int>() == type<int?>());
- Expect.isTrue(legacyType<int>() == type<int>());
- Expect.isTrue(legacyType<int>() == legacyType<int>());
-
- Expect.isTrue(listType<int>() == legacyListType<int>());
}
diff --git a/tests/language/nnbd/type_object/equality_weak_test.dart b/tests/language/nnbd/type_object/equality_weak_test.dart
new file mode 100644
index 0000000..dfbb369
--- /dev/null
+++ b/tests/language/nnbd/type_object/equality_weak_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Can't run in strong mode since it contains a legacy library.
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+import "legacy_library.dart";
+
+class A {}
+
+class B {}
+
+Type type<T>() => T;
+
+Type listType<T>() => <T>[].runtimeType;
+
+main() {
+ Expect.isFalse(type<int?>() == legacyType<int>());
+ Expect.isTrue(type<int>() == legacyType<int>());
+ Expect.isFalse(legacyType<int>() == type<int?>());
+ Expect.isTrue(legacyType<int>() == type<int>());
+ Expect.isTrue(legacyType<int>() == legacyType<int>());
+
+ Expect.isTrue(listType<int>() == legacyListType<int>());
+}
diff --git a/tests/language_2/call/constructor_on_unresolvable_class_test.dart b/tests/language_2/call/constructor_on_unresolvable_class_test.dart
index d068b53..f3fa482 100644
--- a/tests/language_2/call/constructor_on_unresolvable_class_test.dart
+++ b/tests/language_2/call/constructor_on_unresolvable_class_test.dart
@@ -11,14 +11,14 @@
main() {
new A();
// ^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A'.
new A.foo();
// ^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A.foo'.
new lib.A();
// ^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'lib.A'.
}
diff --git a/tests/language_2/class/variable_shadow_class_test.dart b/tests/language_2/class/variable_shadow_class_test.dart
index d82fef7..35a1fda 100644
--- a/tests/language_2/class/variable_shadow_class_test.dart
+++ b/tests/language_2/class/variable_shadow_class_test.dart
@@ -15,8 +15,9 @@
var Test;
// Now this refers to the variable.
var i = new Test.named(10);
- // ^^^^
+ // ^^^^^^^^^^
// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+ // ^^^^
// [cfe] Method not found: 'Test.named'.
Expect.equals(10, i.field);
}
diff --git a/tests/language_2/constructor/reference_test.dart b/tests/language_2/constructor/reference_test.dart
index 52e1235..cecfbf3 100644
--- a/tests/language_2/constructor/reference_test.dart
+++ b/tests/language_2/constructor/reference_test.dart
@@ -13,7 +13,7 @@
new Foo.bar();
new Foo.bar.baz();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
new Foo<int>();
@@ -33,13 +33,13 @@
new Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+ // ^^^^^^^
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
new Foo.bar.baz<int>();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^^^
// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
// [cfe] A constructor invocation can't have type arguments on the constructor name.
@@ -50,7 +50,7 @@
const Foo.bar();
const Foo.bar.baz();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
const Foo<int>();
@@ -70,13 +70,13 @@
const Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+ // ^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
const Foo.bar.baz<int>();
// ^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_TYPE
// ^^^
// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
// [cfe] A constructor invocation can't have type arguments on the constructor name.
@@ -106,8 +106,8 @@
Foo.bar<int>.baz();
// ^
// [cfe] A constructor invocation can't have type arguments on the constructor name.
- // ^^^^^
- // [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
+//^^^^^^^
+// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// ^
// [cfe] Method not found: 'Foo.bar.baz'.
Foo.bar.baz<int>();
diff --git a/tests/language_2/interface/interface2_test.dart b/tests/language_2/interface/interface2_test.dart
index 7b8282c..6a0a762 100644
--- a/tests/language_2/interface/interface2_test.dart
+++ b/tests/language_2/interface/interface2_test.dart
@@ -8,8 +8,6 @@
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_NON_CLASS
// [cfe] Type 'BooHoo' not found.
-// ^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
main() {
Interface2NegativeTest();
diff --git a/tests/language_2/malformed/inheritance_test.dart b/tests/language_2/malformed/inheritance_test.dart
index e82cc7a..55154d7 100644
--- a/tests/language_2/malformed/inheritance_test.dart
+++ b/tests/language_2/malformed/inheritance_test.dart
@@ -12,8 +12,6 @@
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTENDS_NON_CLASS
// [cfe] Type 'Unresolved' not found.
- // ^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
{
}
@@ -32,8 +30,6 @@
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.MIXIN_OF_NON_CLASS
// [cfe] Type 'Unresolved' not found.
- // ^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
{
}
@@ -50,8 +46,6 @@
// ^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_NON_CLASS
// [cfe] Type 'Unresolved' not found.
- // ^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
{
}
diff --git a/tests/language_2/malformed/malformed_test.dart b/tests/language_2/malformed/malformed_test.dart
index 2a11ce8..e2ee13a 100644
--- a/tests/language_2/malformed/malformed_test.dart
+++ b/tests/language_2/malformed/malformed_test.dart
@@ -105,11 +105,11 @@
new undeclared_prefix.Unresolved();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'undeclared_prefix.Unresolved'.
new undeclared_prefix.Unresolved<int>();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'undeclared_prefix.Unresolved'.
try {
diff --git a/tests/language_2/new/create_unresolved_type_test.dart b/tests/language_2/new/create_unresolved_type_test.dart
index 296859c..b1ce560 100644
--- a/tests/language_2/new/create_unresolved_type_test.dart
+++ b/tests/language_2/new/create_unresolved_type_test.dart
@@ -5,6 +5,6 @@
main() {
new F<int>();
// ^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'F'.
}
diff --git a/tests/language_2/prefix/transitive_import_prefix_test.dart b/tests/language_2/prefix/transitive_import_prefix_test.dart
index 5146240..9186560 100644
--- a/tests/language_2/prefix/transitive_import_prefix_test.dart
+++ b/tests/language_2/prefix/transitive_import_prefix_test.dart
@@ -7,7 +7,7 @@
// Library prefixes in the imported libraries should not be visible here.
new lib11.Library11(1);
// ^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'lib11.Library11'.
lib11.Library11.static_func();
//^^^^^
diff --git a/tests/language_2/prefix/unresolved_class_test.dart b/tests/language_2/prefix/unresolved_class_test.dart
index 901063c..dd46a62 100644
--- a/tests/language_2/prefix/unresolved_class_test.dart
+++ b/tests/language_2/prefix/unresolved_class_test.dart
@@ -10,8 +10,6 @@
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTENDS_NON_CLASS
// [cfe] Type 'lib12.Library13' not found.
- // ^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
{}
class Implementer
@@ -19,8 +17,6 @@
// ^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_NON_CLASS
// [cfe] Type 'lib12.Library13' not found.
- // ^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
{}
main() {
diff --git a/tests/language_2/private/access_test.dart b/tests/language_2/private/access_test.dart
index 2851659..a1cf6a1 100644
--- a/tests/language_2/private/access_test.dart
+++ b/tests/language_2/private/access_test.dart
@@ -19,7 +19,7 @@
// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_FUNCTION
new _Class();
// ^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: '_Class'.
private._Class();
//^
diff --git a/tests/language_2/regress/regress21793_test.dart b/tests/language_2/regress/regress21793_test.dart
index 6b8e87e..d767690 100644
--- a/tests/language_2/regress/regress21793_test.dart
+++ b/tests/language_2/regress/regress21793_test.dart
@@ -15,6 +15,6 @@
main() {
print(new A()(499));
// ^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+ // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A'.
}
diff --git a/tests/language_2/regress/regress34495_test.dart b/tests/language_2/regress/regress34495_test.dart
index dee281c..cce9bfe 100644
--- a/tests/language_2/regress/regress34495_test.dart
+++ b/tests/language_2/regress/regress34495_test.dart
@@ -4,7 +4,7 @@
final foo = A<B>.foo();
// ^
-// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CLASS
+// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
// [cfe] Method not found: 'A'.
// ^
// [analyzer] STATIC_TYPE_WARNING.NON_TYPE_AS_TYPE_ARGUMENT
diff --git a/tests/language_2/regress/regress41983_test.dart b/tests/language_2/regress/regress41983_test.dart
new file mode 100644
index 0000000..87f9519
--- /dev/null
+++ b/tests/language_2/regress/regress41983_test.dart
@@ -0,0 +1,20014 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+ List<int> ints = new List<int>()
+ ..add(0)
+ ..add(1)
+ ..add(2)
+ ..add(3)
+ ..add(4)
+ ..add(5)
+ ..add(6)
+ ..add(7)
+ ..add(8)
+ ..add(9)
+ ..add(10)
+ ..add(11)
+ ..add(12)
+ ..add(13)
+ ..add(14)
+ ..add(15)
+ ..add(16)
+ ..add(17)
+ ..add(18)
+ ..add(19)
+ ..add(20)
+ ..add(21)
+ ..add(22)
+ ..add(23)
+ ..add(24)
+ ..add(25)
+ ..add(26)
+ ..add(27)
+ ..add(28)
+ ..add(29)
+ ..add(30)
+ ..add(31)
+ ..add(32)
+ ..add(33)
+ ..add(34)
+ ..add(35)
+ ..add(36)
+ ..add(37)
+ ..add(38)
+ ..add(39)
+ ..add(40)
+ ..add(41)
+ ..add(42)
+ ..add(43)
+ ..add(44)
+ ..add(45)
+ ..add(46)
+ ..add(47)
+ ..add(48)
+ ..add(49)
+ ..add(50)
+ ..add(51)
+ ..add(52)
+ ..add(53)
+ ..add(54)
+ ..add(55)
+ ..add(56)
+ ..add(57)
+ ..add(58)
+ ..add(59)
+ ..add(60)
+ ..add(61)
+ ..add(62)
+ ..add(63)
+ ..add(64)
+ ..add(65)
+ ..add(66)
+ ..add(67)
+ ..add(68)
+ ..add(69)
+ ..add(70)
+ ..add(71)
+ ..add(72)
+ ..add(73)
+ ..add(74)
+ ..add(75)
+ ..add(76)
+ ..add(77)
+ ..add(78)
+ ..add(79)
+ ..add(80)
+ ..add(81)
+ ..add(82)
+ ..add(83)
+ ..add(84)
+ ..add(85)
+ ..add(86)
+ ..add(87)
+ ..add(88)
+ ..add(89)
+ ..add(90)
+ ..add(91)
+ ..add(92)
+ ..add(93)
+ ..add(94)
+ ..add(95)
+ ..add(96)
+ ..add(97)
+ ..add(98)
+ ..add(99)
+ ..add(100)
+ ..add(101)
+ ..add(102)
+ ..add(103)
+ ..add(104)
+ ..add(105)
+ ..add(106)
+ ..add(107)
+ ..add(108)
+ ..add(109)
+ ..add(110)
+ ..add(111)
+ ..add(112)
+ ..add(113)
+ ..add(114)
+ ..add(115)
+ ..add(116)
+ ..add(117)
+ ..add(118)
+ ..add(119)
+ ..add(120)
+ ..add(121)
+ ..add(122)
+ ..add(123)
+ ..add(124)
+ ..add(125)
+ ..add(126)
+ ..add(127)
+ ..add(128)
+ ..add(129)
+ ..add(130)
+ ..add(131)
+ ..add(132)
+ ..add(133)
+ ..add(134)
+ ..add(135)
+ ..add(136)
+ ..add(137)
+ ..add(138)
+ ..add(139)
+ ..add(140)
+ ..add(141)
+ ..add(142)
+ ..add(143)
+ ..add(144)
+ ..add(145)
+ ..add(146)
+ ..add(147)
+ ..add(148)
+ ..add(149)
+ ..add(150)
+ ..add(151)
+ ..add(152)
+ ..add(153)
+ ..add(154)
+ ..add(155)
+ ..add(156)
+ ..add(157)
+ ..add(158)
+ ..add(159)
+ ..add(160)
+ ..add(161)
+ ..add(162)
+ ..add(163)
+ ..add(164)
+ ..add(165)
+ ..add(166)
+ ..add(167)
+ ..add(168)
+ ..add(169)
+ ..add(170)
+ ..add(171)
+ ..add(172)
+ ..add(173)
+ ..add(174)
+ ..add(175)
+ ..add(176)
+ ..add(177)
+ ..add(178)
+ ..add(179)
+ ..add(180)
+ ..add(181)
+ ..add(182)
+ ..add(183)
+ ..add(184)
+ ..add(185)
+ ..add(186)
+ ..add(187)
+ ..add(188)
+ ..add(189)
+ ..add(190)
+ ..add(191)
+ ..add(192)
+ ..add(193)
+ ..add(194)
+ ..add(195)
+ ..add(196)
+ ..add(197)
+ ..add(198)
+ ..add(199)
+ ..add(200)
+ ..add(201)
+ ..add(202)
+ ..add(203)
+ ..add(204)
+ ..add(205)
+ ..add(206)
+ ..add(207)
+ ..add(208)
+ ..add(209)
+ ..add(210)
+ ..add(211)
+ ..add(212)
+ ..add(213)
+ ..add(214)
+ ..add(215)
+ ..add(216)
+ ..add(217)
+ ..add(218)
+ ..add(219)
+ ..add(220)
+ ..add(221)
+ ..add(222)
+ ..add(223)
+ ..add(224)
+ ..add(225)
+ ..add(226)
+ ..add(227)
+ ..add(228)
+ ..add(229)
+ ..add(230)
+ ..add(231)
+ ..add(232)
+ ..add(233)
+ ..add(234)
+ ..add(235)
+ ..add(236)
+ ..add(237)
+ ..add(238)
+ ..add(239)
+ ..add(240)
+ ..add(241)
+ ..add(242)
+ ..add(243)
+ ..add(244)
+ ..add(245)
+ ..add(246)
+ ..add(247)
+ ..add(248)
+ ..add(249)
+ ..add(250)
+ ..add(251)
+ ..add(252)
+ ..add(253)
+ ..add(254)
+ ..add(255)
+ ..add(256)
+ ..add(257)
+ ..add(258)
+ ..add(259)
+ ..add(260)
+ ..add(261)
+ ..add(262)
+ ..add(263)
+ ..add(264)
+ ..add(265)
+ ..add(266)
+ ..add(267)
+ ..add(268)
+ ..add(269)
+ ..add(270)
+ ..add(271)
+ ..add(272)
+ ..add(273)
+ ..add(274)
+ ..add(275)
+ ..add(276)
+ ..add(277)
+ ..add(278)
+ ..add(279)
+ ..add(280)
+ ..add(281)
+ ..add(282)
+ ..add(283)
+ ..add(284)
+ ..add(285)
+ ..add(286)
+ ..add(287)
+ ..add(288)
+ ..add(289)
+ ..add(290)
+ ..add(291)
+ ..add(292)
+ ..add(293)
+ ..add(294)
+ ..add(295)
+ ..add(296)
+ ..add(297)
+ ..add(298)
+ ..add(299)
+ ..add(300)
+ ..add(301)
+ ..add(302)
+ ..add(303)
+ ..add(304)
+ ..add(305)
+ ..add(306)
+ ..add(307)
+ ..add(308)
+ ..add(309)
+ ..add(310)
+ ..add(311)
+ ..add(312)
+ ..add(313)
+ ..add(314)
+ ..add(315)
+ ..add(316)
+ ..add(317)
+ ..add(318)
+ ..add(319)
+ ..add(320)
+ ..add(321)
+ ..add(322)
+ ..add(323)
+ ..add(324)
+ ..add(325)
+ ..add(326)
+ ..add(327)
+ ..add(328)
+ ..add(329)
+ ..add(330)
+ ..add(331)
+ ..add(332)
+ ..add(333)
+ ..add(334)
+ ..add(335)
+ ..add(336)
+ ..add(337)
+ ..add(338)
+ ..add(339)
+ ..add(340)
+ ..add(341)
+ ..add(342)
+ ..add(343)
+ ..add(344)
+ ..add(345)
+ ..add(346)
+ ..add(347)
+ ..add(348)
+ ..add(349)
+ ..add(350)
+ ..add(351)
+ ..add(352)
+ ..add(353)
+ ..add(354)
+ ..add(355)
+ ..add(356)
+ ..add(357)
+ ..add(358)
+ ..add(359)
+ ..add(360)
+ ..add(361)
+ ..add(362)
+ ..add(363)
+ ..add(364)
+ ..add(365)
+ ..add(366)
+ ..add(367)
+ ..add(368)
+ ..add(369)
+ ..add(370)
+ ..add(371)
+ ..add(372)
+ ..add(373)
+ ..add(374)
+ ..add(375)
+ ..add(376)
+ ..add(377)
+ ..add(378)
+ ..add(379)
+ ..add(380)
+ ..add(381)
+ ..add(382)
+ ..add(383)
+ ..add(384)
+ ..add(385)
+ ..add(386)
+ ..add(387)
+ ..add(388)
+ ..add(389)
+ ..add(390)
+ ..add(391)
+ ..add(392)
+ ..add(393)
+ ..add(394)
+ ..add(395)
+ ..add(396)
+ ..add(397)
+ ..add(398)
+ ..add(399)
+ ..add(400)
+ ..add(401)
+ ..add(402)
+ ..add(403)
+ ..add(404)
+ ..add(405)
+ ..add(406)
+ ..add(407)
+ ..add(408)
+ ..add(409)
+ ..add(410)
+ ..add(411)
+ ..add(412)
+ ..add(413)
+ ..add(414)
+ ..add(415)
+ ..add(416)
+ ..add(417)
+ ..add(418)
+ ..add(419)
+ ..add(420)
+ ..add(421)
+ ..add(422)
+ ..add(423)
+ ..add(424)
+ ..add(425)
+ ..add(426)
+ ..add(427)
+ ..add(428)
+ ..add(429)
+ ..add(430)
+ ..add(431)
+ ..add(432)
+ ..add(433)
+ ..add(434)
+ ..add(435)
+ ..add(436)
+ ..add(437)
+ ..add(438)
+ ..add(439)
+ ..add(440)
+ ..add(441)
+ ..add(442)
+ ..add(443)
+ ..add(444)
+ ..add(445)
+ ..add(446)
+ ..add(447)
+ ..add(448)
+ ..add(449)
+ ..add(450)
+ ..add(451)
+ ..add(452)
+ ..add(453)
+ ..add(454)
+ ..add(455)
+ ..add(456)
+ ..add(457)
+ ..add(458)
+ ..add(459)
+ ..add(460)
+ ..add(461)
+ ..add(462)
+ ..add(463)
+ ..add(464)
+ ..add(465)
+ ..add(466)
+ ..add(467)
+ ..add(468)
+ ..add(469)
+ ..add(470)
+ ..add(471)
+ ..add(472)
+ ..add(473)
+ ..add(474)
+ ..add(475)
+ ..add(476)
+ ..add(477)
+ ..add(478)
+ ..add(479)
+ ..add(480)
+ ..add(481)
+ ..add(482)
+ ..add(483)
+ ..add(484)
+ ..add(485)
+ ..add(486)
+ ..add(487)
+ ..add(488)
+ ..add(489)
+ ..add(490)
+ ..add(491)
+ ..add(492)
+ ..add(493)
+ ..add(494)
+ ..add(495)
+ ..add(496)
+ ..add(497)
+ ..add(498)
+ ..add(499)
+ ..add(500)
+ ..add(501)
+ ..add(502)
+ ..add(503)
+ ..add(504)
+ ..add(505)
+ ..add(506)
+ ..add(507)
+ ..add(508)
+ ..add(509)
+ ..add(510)
+ ..add(511)
+ ..add(512)
+ ..add(513)
+ ..add(514)
+ ..add(515)
+ ..add(516)
+ ..add(517)
+ ..add(518)
+ ..add(519)
+ ..add(520)
+ ..add(521)
+ ..add(522)
+ ..add(523)
+ ..add(524)
+ ..add(525)
+ ..add(526)
+ ..add(527)
+ ..add(528)
+ ..add(529)
+ ..add(530)
+ ..add(531)
+ ..add(532)
+ ..add(533)
+ ..add(534)
+ ..add(535)
+ ..add(536)
+ ..add(537)
+ ..add(538)
+ ..add(539)
+ ..add(540)
+ ..add(541)
+ ..add(542)
+ ..add(543)
+ ..add(544)
+ ..add(545)
+ ..add(546)
+ ..add(547)
+ ..add(548)
+ ..add(549)
+ ..add(550)
+ ..add(551)
+ ..add(552)
+ ..add(553)
+ ..add(554)
+ ..add(555)
+ ..add(556)
+ ..add(557)
+ ..add(558)
+ ..add(559)
+ ..add(560)
+ ..add(561)
+ ..add(562)
+ ..add(563)
+ ..add(564)
+ ..add(565)
+ ..add(566)
+ ..add(567)
+ ..add(568)
+ ..add(569)
+ ..add(570)
+ ..add(571)
+ ..add(572)
+ ..add(573)
+ ..add(574)
+ ..add(575)
+ ..add(576)
+ ..add(577)
+ ..add(578)
+ ..add(579)
+ ..add(580)
+ ..add(581)
+ ..add(582)
+ ..add(583)
+ ..add(584)
+ ..add(585)
+ ..add(586)
+ ..add(587)
+ ..add(588)
+ ..add(589)
+ ..add(590)
+ ..add(591)
+ ..add(592)
+ ..add(593)
+ ..add(594)
+ ..add(595)
+ ..add(596)
+ ..add(597)
+ ..add(598)
+ ..add(599)
+ ..add(600)
+ ..add(601)
+ ..add(602)
+ ..add(603)
+ ..add(604)
+ ..add(605)
+ ..add(606)
+ ..add(607)
+ ..add(608)
+ ..add(609)
+ ..add(610)
+ ..add(611)
+ ..add(612)
+ ..add(613)
+ ..add(614)
+ ..add(615)
+ ..add(616)
+ ..add(617)
+ ..add(618)
+ ..add(619)
+ ..add(620)
+ ..add(621)
+ ..add(622)
+ ..add(623)
+ ..add(624)
+ ..add(625)
+ ..add(626)
+ ..add(627)
+ ..add(628)
+ ..add(629)
+ ..add(630)
+ ..add(631)
+ ..add(632)
+ ..add(633)
+ ..add(634)
+ ..add(635)
+ ..add(636)
+ ..add(637)
+ ..add(638)
+ ..add(639)
+ ..add(640)
+ ..add(641)
+ ..add(642)
+ ..add(643)
+ ..add(644)
+ ..add(645)
+ ..add(646)
+ ..add(647)
+ ..add(648)
+ ..add(649)
+ ..add(650)
+ ..add(651)
+ ..add(652)
+ ..add(653)
+ ..add(654)
+ ..add(655)
+ ..add(656)
+ ..add(657)
+ ..add(658)
+ ..add(659)
+ ..add(660)
+ ..add(661)
+ ..add(662)
+ ..add(663)
+ ..add(664)
+ ..add(665)
+ ..add(666)
+ ..add(667)
+ ..add(668)
+ ..add(669)
+ ..add(670)
+ ..add(671)
+ ..add(672)
+ ..add(673)
+ ..add(674)
+ ..add(675)
+ ..add(676)
+ ..add(677)
+ ..add(678)
+ ..add(679)
+ ..add(680)
+ ..add(681)
+ ..add(682)
+ ..add(683)
+ ..add(684)
+ ..add(685)
+ ..add(686)
+ ..add(687)
+ ..add(688)
+ ..add(689)
+ ..add(690)
+ ..add(691)
+ ..add(692)
+ ..add(693)
+ ..add(694)
+ ..add(695)
+ ..add(696)
+ ..add(697)
+ ..add(698)
+ ..add(699)
+ ..add(700)
+ ..add(701)
+ ..add(702)
+ ..add(703)
+ ..add(704)
+ ..add(705)
+ ..add(706)
+ ..add(707)
+ ..add(708)
+ ..add(709)
+ ..add(710)
+ ..add(711)
+ ..add(712)
+ ..add(713)
+ ..add(714)
+ ..add(715)
+ ..add(716)
+ ..add(717)
+ ..add(718)
+ ..add(719)
+ ..add(720)
+ ..add(721)
+ ..add(722)
+ ..add(723)
+ ..add(724)
+ ..add(725)
+ ..add(726)
+ ..add(727)
+ ..add(728)
+ ..add(729)
+ ..add(730)
+ ..add(731)
+ ..add(732)
+ ..add(733)
+ ..add(734)
+ ..add(735)
+ ..add(736)
+ ..add(737)
+ ..add(738)
+ ..add(739)
+ ..add(740)
+ ..add(741)
+ ..add(742)
+ ..add(743)
+ ..add(744)
+ ..add(745)
+ ..add(746)
+ ..add(747)
+ ..add(748)
+ ..add(749)
+ ..add(750)
+ ..add(751)
+ ..add(752)
+ ..add(753)
+ ..add(754)
+ ..add(755)
+ ..add(756)
+ ..add(757)
+ ..add(758)
+ ..add(759)
+ ..add(760)
+ ..add(761)
+ ..add(762)
+ ..add(763)
+ ..add(764)
+ ..add(765)
+ ..add(766)
+ ..add(767)
+ ..add(768)
+ ..add(769)
+ ..add(770)
+ ..add(771)
+ ..add(772)
+ ..add(773)
+ ..add(774)
+ ..add(775)
+ ..add(776)
+ ..add(777)
+ ..add(778)
+ ..add(779)
+ ..add(780)
+ ..add(781)
+ ..add(782)
+ ..add(783)
+ ..add(784)
+ ..add(785)
+ ..add(786)
+ ..add(787)
+ ..add(788)
+ ..add(789)
+ ..add(790)
+ ..add(791)
+ ..add(792)
+ ..add(793)
+ ..add(794)
+ ..add(795)
+ ..add(796)
+ ..add(797)
+ ..add(798)
+ ..add(799)
+ ..add(800)
+ ..add(801)
+ ..add(802)
+ ..add(803)
+ ..add(804)
+ ..add(805)
+ ..add(806)
+ ..add(807)
+ ..add(808)
+ ..add(809)
+ ..add(810)
+ ..add(811)
+ ..add(812)
+ ..add(813)
+ ..add(814)
+ ..add(815)
+ ..add(816)
+ ..add(817)
+ ..add(818)
+ ..add(819)
+ ..add(820)
+ ..add(821)
+ ..add(822)
+ ..add(823)
+ ..add(824)
+ ..add(825)
+ ..add(826)
+ ..add(827)
+ ..add(828)
+ ..add(829)
+ ..add(830)
+ ..add(831)
+ ..add(832)
+ ..add(833)
+ ..add(834)
+ ..add(835)
+ ..add(836)
+ ..add(837)
+ ..add(838)
+ ..add(839)
+ ..add(840)
+ ..add(841)
+ ..add(842)
+ ..add(843)
+ ..add(844)
+ ..add(845)
+ ..add(846)
+ ..add(847)
+ ..add(848)
+ ..add(849)
+ ..add(850)
+ ..add(851)
+ ..add(852)
+ ..add(853)
+ ..add(854)
+ ..add(855)
+ ..add(856)
+ ..add(857)
+ ..add(858)
+ ..add(859)
+ ..add(860)
+ ..add(861)
+ ..add(862)
+ ..add(863)
+ ..add(864)
+ ..add(865)
+ ..add(866)
+ ..add(867)
+ ..add(868)
+ ..add(869)
+ ..add(870)
+ ..add(871)
+ ..add(872)
+ ..add(873)
+ ..add(874)
+ ..add(875)
+ ..add(876)
+ ..add(877)
+ ..add(878)
+ ..add(879)
+ ..add(880)
+ ..add(881)
+ ..add(882)
+ ..add(883)
+ ..add(884)
+ ..add(885)
+ ..add(886)
+ ..add(887)
+ ..add(888)
+ ..add(889)
+ ..add(890)
+ ..add(891)
+ ..add(892)
+ ..add(893)
+ ..add(894)
+ ..add(895)
+ ..add(896)
+ ..add(897)
+ ..add(898)
+ ..add(899)
+ ..add(900)
+ ..add(901)
+ ..add(902)
+ ..add(903)
+ ..add(904)
+ ..add(905)
+ ..add(906)
+ ..add(907)
+ ..add(908)
+ ..add(909)
+ ..add(910)
+ ..add(911)
+ ..add(912)
+ ..add(913)
+ ..add(914)
+ ..add(915)
+ ..add(916)
+ ..add(917)
+ ..add(918)
+ ..add(919)
+ ..add(920)
+ ..add(921)
+ ..add(922)
+ ..add(923)
+ ..add(924)
+ ..add(925)
+ ..add(926)
+ ..add(927)
+ ..add(928)
+ ..add(929)
+ ..add(930)
+ ..add(931)
+ ..add(932)
+ ..add(933)
+ ..add(934)
+ ..add(935)
+ ..add(936)
+ ..add(937)
+ ..add(938)
+ ..add(939)
+ ..add(940)
+ ..add(941)
+ ..add(942)
+ ..add(943)
+ ..add(944)
+ ..add(945)
+ ..add(946)
+ ..add(947)
+ ..add(948)
+ ..add(949)
+ ..add(950)
+ ..add(951)
+ ..add(952)
+ ..add(953)
+ ..add(954)
+ ..add(955)
+ ..add(956)
+ ..add(957)
+ ..add(958)
+ ..add(959)
+ ..add(960)
+ ..add(961)
+ ..add(962)
+ ..add(963)
+ ..add(964)
+ ..add(965)
+ ..add(966)
+ ..add(967)
+ ..add(968)
+ ..add(969)
+ ..add(970)
+ ..add(971)
+ ..add(972)
+ ..add(973)
+ ..add(974)
+ ..add(975)
+ ..add(976)
+ ..add(977)
+ ..add(978)
+ ..add(979)
+ ..add(980)
+ ..add(981)
+ ..add(982)
+ ..add(983)
+ ..add(984)
+ ..add(985)
+ ..add(986)
+ ..add(987)
+ ..add(988)
+ ..add(989)
+ ..add(990)
+ ..add(991)
+ ..add(992)
+ ..add(993)
+ ..add(994)
+ ..add(995)
+ ..add(996)
+ ..add(997)
+ ..add(998)
+ ..add(999)
+ ..add(1000)
+ ..add(1001)
+ ..add(1002)
+ ..add(1003)
+ ..add(1004)
+ ..add(1005)
+ ..add(1006)
+ ..add(1007)
+ ..add(1008)
+ ..add(1009)
+ ..add(1010)
+ ..add(1011)
+ ..add(1012)
+ ..add(1013)
+ ..add(1014)
+ ..add(1015)
+ ..add(1016)
+ ..add(1017)
+ ..add(1018)
+ ..add(1019)
+ ..add(1020)
+ ..add(1021)
+ ..add(1022)
+ ..add(1023)
+ ..add(1024)
+ ..add(1025)
+ ..add(1026)
+ ..add(1027)
+ ..add(1028)
+ ..add(1029)
+ ..add(1030)
+ ..add(1031)
+ ..add(1032)
+ ..add(1033)
+ ..add(1034)
+ ..add(1035)
+ ..add(1036)
+ ..add(1037)
+ ..add(1038)
+ ..add(1039)
+ ..add(1040)
+ ..add(1041)
+ ..add(1042)
+ ..add(1043)
+ ..add(1044)
+ ..add(1045)
+ ..add(1046)
+ ..add(1047)
+ ..add(1048)
+ ..add(1049)
+ ..add(1050)
+ ..add(1051)
+ ..add(1052)
+ ..add(1053)
+ ..add(1054)
+ ..add(1055)
+ ..add(1056)
+ ..add(1057)
+ ..add(1058)
+ ..add(1059)
+ ..add(1060)
+ ..add(1061)
+ ..add(1062)
+ ..add(1063)
+ ..add(1064)
+ ..add(1065)
+ ..add(1066)
+ ..add(1067)
+ ..add(1068)
+ ..add(1069)
+ ..add(1070)
+ ..add(1071)
+ ..add(1072)
+ ..add(1073)
+ ..add(1074)
+ ..add(1075)
+ ..add(1076)
+ ..add(1077)
+ ..add(1078)
+ ..add(1079)
+ ..add(1080)
+ ..add(1081)
+ ..add(1082)
+ ..add(1083)
+ ..add(1084)
+ ..add(1085)
+ ..add(1086)
+ ..add(1087)
+ ..add(1088)
+ ..add(1089)
+ ..add(1090)
+ ..add(1091)
+ ..add(1092)
+ ..add(1093)
+ ..add(1094)
+ ..add(1095)
+ ..add(1096)
+ ..add(1097)
+ ..add(1098)
+ ..add(1099)
+ ..add(1100)
+ ..add(1101)
+ ..add(1102)
+ ..add(1103)
+ ..add(1104)
+ ..add(1105)
+ ..add(1106)
+ ..add(1107)
+ ..add(1108)
+ ..add(1109)
+ ..add(1110)
+ ..add(1111)
+ ..add(1112)
+ ..add(1113)
+ ..add(1114)
+ ..add(1115)
+ ..add(1116)
+ ..add(1117)
+ ..add(1118)
+ ..add(1119)
+ ..add(1120)
+ ..add(1121)
+ ..add(1122)
+ ..add(1123)
+ ..add(1124)
+ ..add(1125)
+ ..add(1126)
+ ..add(1127)
+ ..add(1128)
+ ..add(1129)
+ ..add(1130)
+ ..add(1131)
+ ..add(1132)
+ ..add(1133)
+ ..add(1134)
+ ..add(1135)
+ ..add(1136)
+ ..add(1137)
+ ..add(1138)
+ ..add(1139)
+ ..add(1140)
+ ..add(1141)
+ ..add(1142)
+ ..add(1143)
+ ..add(1144)
+ ..add(1145)
+ ..add(1146)
+ ..add(1147)
+ ..add(1148)
+ ..add(1149)
+ ..add(1150)
+ ..add(1151)
+ ..add(1152)
+ ..add(1153)
+ ..add(1154)
+ ..add(1155)
+ ..add(1156)
+ ..add(1157)
+ ..add(1158)
+ ..add(1159)
+ ..add(1160)
+ ..add(1161)
+ ..add(1162)
+ ..add(1163)
+ ..add(1164)
+ ..add(1165)
+ ..add(1166)
+ ..add(1167)
+ ..add(1168)
+ ..add(1169)
+ ..add(1170)
+ ..add(1171)
+ ..add(1172)
+ ..add(1173)
+ ..add(1174)
+ ..add(1175)
+ ..add(1176)
+ ..add(1177)
+ ..add(1178)
+ ..add(1179)
+ ..add(1180)
+ ..add(1181)
+ ..add(1182)
+ ..add(1183)
+ ..add(1184)
+ ..add(1185)
+ ..add(1186)
+ ..add(1187)
+ ..add(1188)
+ ..add(1189)
+ ..add(1190)
+ ..add(1191)
+ ..add(1192)
+ ..add(1193)
+ ..add(1194)
+ ..add(1195)
+ ..add(1196)
+ ..add(1197)
+ ..add(1198)
+ ..add(1199)
+ ..add(1200)
+ ..add(1201)
+ ..add(1202)
+ ..add(1203)
+ ..add(1204)
+ ..add(1205)
+ ..add(1206)
+ ..add(1207)
+ ..add(1208)
+ ..add(1209)
+ ..add(1210)
+ ..add(1211)
+ ..add(1212)
+ ..add(1213)
+ ..add(1214)
+ ..add(1215)
+ ..add(1216)
+ ..add(1217)
+ ..add(1218)
+ ..add(1219)
+ ..add(1220)
+ ..add(1221)
+ ..add(1222)
+ ..add(1223)
+ ..add(1224)
+ ..add(1225)
+ ..add(1226)
+ ..add(1227)
+ ..add(1228)
+ ..add(1229)
+ ..add(1230)
+ ..add(1231)
+ ..add(1232)
+ ..add(1233)
+ ..add(1234)
+ ..add(1235)
+ ..add(1236)
+ ..add(1237)
+ ..add(1238)
+ ..add(1239)
+ ..add(1240)
+ ..add(1241)
+ ..add(1242)
+ ..add(1243)
+ ..add(1244)
+ ..add(1245)
+ ..add(1246)
+ ..add(1247)
+ ..add(1248)
+ ..add(1249)
+ ..add(1250)
+ ..add(1251)
+ ..add(1252)
+ ..add(1253)
+ ..add(1254)
+ ..add(1255)
+ ..add(1256)
+ ..add(1257)
+ ..add(1258)
+ ..add(1259)
+ ..add(1260)
+ ..add(1261)
+ ..add(1262)
+ ..add(1263)
+ ..add(1264)
+ ..add(1265)
+ ..add(1266)
+ ..add(1267)
+ ..add(1268)
+ ..add(1269)
+ ..add(1270)
+ ..add(1271)
+ ..add(1272)
+ ..add(1273)
+ ..add(1274)
+ ..add(1275)
+ ..add(1276)
+ ..add(1277)
+ ..add(1278)
+ ..add(1279)
+ ..add(1280)
+ ..add(1281)
+ ..add(1282)
+ ..add(1283)
+ ..add(1284)
+ ..add(1285)
+ ..add(1286)
+ ..add(1287)
+ ..add(1288)
+ ..add(1289)
+ ..add(1290)
+ ..add(1291)
+ ..add(1292)
+ ..add(1293)
+ ..add(1294)
+ ..add(1295)
+ ..add(1296)
+ ..add(1297)
+ ..add(1298)
+ ..add(1299)
+ ..add(1300)
+ ..add(1301)
+ ..add(1302)
+ ..add(1303)
+ ..add(1304)
+ ..add(1305)
+ ..add(1306)
+ ..add(1307)
+ ..add(1308)
+ ..add(1309)
+ ..add(1310)
+ ..add(1311)
+ ..add(1312)
+ ..add(1313)
+ ..add(1314)
+ ..add(1315)
+ ..add(1316)
+ ..add(1317)
+ ..add(1318)
+ ..add(1319)
+ ..add(1320)
+ ..add(1321)
+ ..add(1322)
+ ..add(1323)
+ ..add(1324)
+ ..add(1325)
+ ..add(1326)
+ ..add(1327)
+ ..add(1328)
+ ..add(1329)
+ ..add(1330)
+ ..add(1331)
+ ..add(1332)
+ ..add(1333)
+ ..add(1334)
+ ..add(1335)
+ ..add(1336)
+ ..add(1337)
+ ..add(1338)
+ ..add(1339)
+ ..add(1340)
+ ..add(1341)
+ ..add(1342)
+ ..add(1343)
+ ..add(1344)
+ ..add(1345)
+ ..add(1346)
+ ..add(1347)
+ ..add(1348)
+ ..add(1349)
+ ..add(1350)
+ ..add(1351)
+ ..add(1352)
+ ..add(1353)
+ ..add(1354)
+ ..add(1355)
+ ..add(1356)
+ ..add(1357)
+ ..add(1358)
+ ..add(1359)
+ ..add(1360)
+ ..add(1361)
+ ..add(1362)
+ ..add(1363)
+ ..add(1364)
+ ..add(1365)
+ ..add(1366)
+ ..add(1367)
+ ..add(1368)
+ ..add(1369)
+ ..add(1370)
+ ..add(1371)
+ ..add(1372)
+ ..add(1373)
+ ..add(1374)
+ ..add(1375)
+ ..add(1376)
+ ..add(1377)
+ ..add(1378)
+ ..add(1379)
+ ..add(1380)
+ ..add(1381)
+ ..add(1382)
+ ..add(1383)
+ ..add(1384)
+ ..add(1385)
+ ..add(1386)
+ ..add(1387)
+ ..add(1388)
+ ..add(1389)
+ ..add(1390)
+ ..add(1391)
+ ..add(1392)
+ ..add(1393)
+ ..add(1394)
+ ..add(1395)
+ ..add(1396)
+ ..add(1397)
+ ..add(1398)
+ ..add(1399)
+ ..add(1400)
+ ..add(1401)
+ ..add(1402)
+ ..add(1403)
+ ..add(1404)
+ ..add(1405)
+ ..add(1406)
+ ..add(1407)
+ ..add(1408)
+ ..add(1409)
+ ..add(1410)
+ ..add(1411)
+ ..add(1412)
+ ..add(1413)
+ ..add(1414)
+ ..add(1415)
+ ..add(1416)
+ ..add(1417)
+ ..add(1418)
+ ..add(1419)
+ ..add(1420)
+ ..add(1421)
+ ..add(1422)
+ ..add(1423)
+ ..add(1424)
+ ..add(1425)
+ ..add(1426)
+ ..add(1427)
+ ..add(1428)
+ ..add(1429)
+ ..add(1430)
+ ..add(1431)
+ ..add(1432)
+ ..add(1433)
+ ..add(1434)
+ ..add(1435)
+ ..add(1436)
+ ..add(1437)
+ ..add(1438)
+ ..add(1439)
+ ..add(1440)
+ ..add(1441)
+ ..add(1442)
+ ..add(1443)
+ ..add(1444)
+ ..add(1445)
+ ..add(1446)
+ ..add(1447)
+ ..add(1448)
+ ..add(1449)
+ ..add(1450)
+ ..add(1451)
+ ..add(1452)
+ ..add(1453)
+ ..add(1454)
+ ..add(1455)
+ ..add(1456)
+ ..add(1457)
+ ..add(1458)
+ ..add(1459)
+ ..add(1460)
+ ..add(1461)
+ ..add(1462)
+ ..add(1463)
+ ..add(1464)
+ ..add(1465)
+ ..add(1466)
+ ..add(1467)
+ ..add(1468)
+ ..add(1469)
+ ..add(1470)
+ ..add(1471)
+ ..add(1472)
+ ..add(1473)
+ ..add(1474)
+ ..add(1475)
+ ..add(1476)
+ ..add(1477)
+ ..add(1478)
+ ..add(1479)
+ ..add(1480)
+ ..add(1481)
+ ..add(1482)
+ ..add(1483)
+ ..add(1484)
+ ..add(1485)
+ ..add(1486)
+ ..add(1487)
+ ..add(1488)
+ ..add(1489)
+ ..add(1490)
+ ..add(1491)
+ ..add(1492)
+ ..add(1493)
+ ..add(1494)
+ ..add(1495)
+ ..add(1496)
+ ..add(1497)
+ ..add(1498)
+ ..add(1499)
+ ..add(1500)
+ ..add(1501)
+ ..add(1502)
+ ..add(1503)
+ ..add(1504)
+ ..add(1505)
+ ..add(1506)
+ ..add(1507)
+ ..add(1508)
+ ..add(1509)
+ ..add(1510)
+ ..add(1511)
+ ..add(1512)
+ ..add(1513)
+ ..add(1514)
+ ..add(1515)
+ ..add(1516)
+ ..add(1517)
+ ..add(1518)
+ ..add(1519)
+ ..add(1520)
+ ..add(1521)
+ ..add(1522)
+ ..add(1523)
+ ..add(1524)
+ ..add(1525)
+ ..add(1526)
+ ..add(1527)
+ ..add(1528)
+ ..add(1529)
+ ..add(1530)
+ ..add(1531)
+ ..add(1532)
+ ..add(1533)
+ ..add(1534)
+ ..add(1535)
+ ..add(1536)
+ ..add(1537)
+ ..add(1538)
+ ..add(1539)
+ ..add(1540)
+ ..add(1541)
+ ..add(1542)
+ ..add(1543)
+ ..add(1544)
+ ..add(1545)
+ ..add(1546)
+ ..add(1547)
+ ..add(1548)
+ ..add(1549)
+ ..add(1550)
+ ..add(1551)
+ ..add(1552)
+ ..add(1553)
+ ..add(1554)
+ ..add(1555)
+ ..add(1556)
+ ..add(1557)
+ ..add(1558)
+ ..add(1559)
+ ..add(1560)
+ ..add(1561)
+ ..add(1562)
+ ..add(1563)
+ ..add(1564)
+ ..add(1565)
+ ..add(1566)
+ ..add(1567)
+ ..add(1568)
+ ..add(1569)
+ ..add(1570)
+ ..add(1571)
+ ..add(1572)
+ ..add(1573)
+ ..add(1574)
+ ..add(1575)
+ ..add(1576)
+ ..add(1577)
+ ..add(1578)
+ ..add(1579)
+ ..add(1580)
+ ..add(1581)
+ ..add(1582)
+ ..add(1583)
+ ..add(1584)
+ ..add(1585)
+ ..add(1586)
+ ..add(1587)
+ ..add(1588)
+ ..add(1589)
+ ..add(1590)
+ ..add(1591)
+ ..add(1592)
+ ..add(1593)
+ ..add(1594)
+ ..add(1595)
+ ..add(1596)
+ ..add(1597)
+ ..add(1598)
+ ..add(1599)
+ ..add(1600)
+ ..add(1601)
+ ..add(1602)
+ ..add(1603)
+ ..add(1604)
+ ..add(1605)
+ ..add(1606)
+ ..add(1607)
+ ..add(1608)
+ ..add(1609)
+ ..add(1610)
+ ..add(1611)
+ ..add(1612)
+ ..add(1613)
+ ..add(1614)
+ ..add(1615)
+ ..add(1616)
+ ..add(1617)
+ ..add(1618)
+ ..add(1619)
+ ..add(1620)
+ ..add(1621)
+ ..add(1622)
+ ..add(1623)
+ ..add(1624)
+ ..add(1625)
+ ..add(1626)
+ ..add(1627)
+ ..add(1628)
+ ..add(1629)
+ ..add(1630)
+ ..add(1631)
+ ..add(1632)
+ ..add(1633)
+ ..add(1634)
+ ..add(1635)
+ ..add(1636)
+ ..add(1637)
+ ..add(1638)
+ ..add(1639)
+ ..add(1640)
+ ..add(1641)
+ ..add(1642)
+ ..add(1643)
+ ..add(1644)
+ ..add(1645)
+ ..add(1646)
+ ..add(1647)
+ ..add(1648)
+ ..add(1649)
+ ..add(1650)
+ ..add(1651)
+ ..add(1652)
+ ..add(1653)
+ ..add(1654)
+ ..add(1655)
+ ..add(1656)
+ ..add(1657)
+ ..add(1658)
+ ..add(1659)
+ ..add(1660)
+ ..add(1661)
+ ..add(1662)
+ ..add(1663)
+ ..add(1664)
+ ..add(1665)
+ ..add(1666)
+ ..add(1667)
+ ..add(1668)
+ ..add(1669)
+ ..add(1670)
+ ..add(1671)
+ ..add(1672)
+ ..add(1673)
+ ..add(1674)
+ ..add(1675)
+ ..add(1676)
+ ..add(1677)
+ ..add(1678)
+ ..add(1679)
+ ..add(1680)
+ ..add(1681)
+ ..add(1682)
+ ..add(1683)
+ ..add(1684)
+ ..add(1685)
+ ..add(1686)
+ ..add(1687)
+ ..add(1688)
+ ..add(1689)
+ ..add(1690)
+ ..add(1691)
+ ..add(1692)
+ ..add(1693)
+ ..add(1694)
+ ..add(1695)
+ ..add(1696)
+ ..add(1697)
+ ..add(1698)
+ ..add(1699)
+ ..add(1700)
+ ..add(1701)
+ ..add(1702)
+ ..add(1703)
+ ..add(1704)
+ ..add(1705)
+ ..add(1706)
+ ..add(1707)
+ ..add(1708)
+ ..add(1709)
+ ..add(1710)
+ ..add(1711)
+ ..add(1712)
+ ..add(1713)
+ ..add(1714)
+ ..add(1715)
+ ..add(1716)
+ ..add(1717)
+ ..add(1718)
+ ..add(1719)
+ ..add(1720)
+ ..add(1721)
+ ..add(1722)
+ ..add(1723)
+ ..add(1724)
+ ..add(1725)
+ ..add(1726)
+ ..add(1727)
+ ..add(1728)
+ ..add(1729)
+ ..add(1730)
+ ..add(1731)
+ ..add(1732)
+ ..add(1733)
+ ..add(1734)
+ ..add(1735)
+ ..add(1736)
+ ..add(1737)
+ ..add(1738)
+ ..add(1739)
+ ..add(1740)
+ ..add(1741)
+ ..add(1742)
+ ..add(1743)
+ ..add(1744)
+ ..add(1745)
+ ..add(1746)
+ ..add(1747)
+ ..add(1748)
+ ..add(1749)
+ ..add(1750)
+ ..add(1751)
+ ..add(1752)
+ ..add(1753)
+ ..add(1754)
+ ..add(1755)
+ ..add(1756)
+ ..add(1757)
+ ..add(1758)
+ ..add(1759)
+ ..add(1760)
+ ..add(1761)
+ ..add(1762)
+ ..add(1763)
+ ..add(1764)
+ ..add(1765)
+ ..add(1766)
+ ..add(1767)
+ ..add(1768)
+ ..add(1769)
+ ..add(1770)
+ ..add(1771)
+ ..add(1772)
+ ..add(1773)
+ ..add(1774)
+ ..add(1775)
+ ..add(1776)
+ ..add(1777)
+ ..add(1778)
+ ..add(1779)
+ ..add(1780)
+ ..add(1781)
+ ..add(1782)
+ ..add(1783)
+ ..add(1784)
+ ..add(1785)
+ ..add(1786)
+ ..add(1787)
+ ..add(1788)
+ ..add(1789)
+ ..add(1790)
+ ..add(1791)
+ ..add(1792)
+ ..add(1793)
+ ..add(1794)
+ ..add(1795)
+ ..add(1796)
+ ..add(1797)
+ ..add(1798)
+ ..add(1799)
+ ..add(1800)
+ ..add(1801)
+ ..add(1802)
+ ..add(1803)
+ ..add(1804)
+ ..add(1805)
+ ..add(1806)
+ ..add(1807)
+ ..add(1808)
+ ..add(1809)
+ ..add(1810)
+ ..add(1811)
+ ..add(1812)
+ ..add(1813)
+ ..add(1814)
+ ..add(1815)
+ ..add(1816)
+ ..add(1817)
+ ..add(1818)
+ ..add(1819)
+ ..add(1820)
+ ..add(1821)
+ ..add(1822)
+ ..add(1823)
+ ..add(1824)
+ ..add(1825)
+ ..add(1826)
+ ..add(1827)
+ ..add(1828)
+ ..add(1829)
+ ..add(1830)
+ ..add(1831)
+ ..add(1832)
+ ..add(1833)
+ ..add(1834)
+ ..add(1835)
+ ..add(1836)
+ ..add(1837)
+ ..add(1838)
+ ..add(1839)
+ ..add(1840)
+ ..add(1841)
+ ..add(1842)
+ ..add(1843)
+ ..add(1844)
+ ..add(1845)
+ ..add(1846)
+ ..add(1847)
+ ..add(1848)
+ ..add(1849)
+ ..add(1850)
+ ..add(1851)
+ ..add(1852)
+ ..add(1853)
+ ..add(1854)
+ ..add(1855)
+ ..add(1856)
+ ..add(1857)
+ ..add(1858)
+ ..add(1859)
+ ..add(1860)
+ ..add(1861)
+ ..add(1862)
+ ..add(1863)
+ ..add(1864)
+ ..add(1865)
+ ..add(1866)
+ ..add(1867)
+ ..add(1868)
+ ..add(1869)
+ ..add(1870)
+ ..add(1871)
+ ..add(1872)
+ ..add(1873)
+ ..add(1874)
+ ..add(1875)
+ ..add(1876)
+ ..add(1877)
+ ..add(1878)
+ ..add(1879)
+ ..add(1880)
+ ..add(1881)
+ ..add(1882)
+ ..add(1883)
+ ..add(1884)
+ ..add(1885)
+ ..add(1886)
+ ..add(1887)
+ ..add(1888)
+ ..add(1889)
+ ..add(1890)
+ ..add(1891)
+ ..add(1892)
+ ..add(1893)
+ ..add(1894)
+ ..add(1895)
+ ..add(1896)
+ ..add(1897)
+ ..add(1898)
+ ..add(1899)
+ ..add(1900)
+ ..add(1901)
+ ..add(1902)
+ ..add(1903)
+ ..add(1904)
+ ..add(1905)
+ ..add(1906)
+ ..add(1907)
+ ..add(1908)
+ ..add(1909)
+ ..add(1910)
+ ..add(1911)
+ ..add(1912)
+ ..add(1913)
+ ..add(1914)
+ ..add(1915)
+ ..add(1916)
+ ..add(1917)
+ ..add(1918)
+ ..add(1919)
+ ..add(1920)
+ ..add(1921)
+ ..add(1922)
+ ..add(1923)
+ ..add(1924)
+ ..add(1925)
+ ..add(1926)
+ ..add(1927)
+ ..add(1928)
+ ..add(1929)
+ ..add(1930)
+ ..add(1931)
+ ..add(1932)
+ ..add(1933)
+ ..add(1934)
+ ..add(1935)
+ ..add(1936)
+ ..add(1937)
+ ..add(1938)
+ ..add(1939)
+ ..add(1940)
+ ..add(1941)
+ ..add(1942)
+ ..add(1943)
+ ..add(1944)
+ ..add(1945)
+ ..add(1946)
+ ..add(1947)
+ ..add(1948)
+ ..add(1949)
+ ..add(1950)
+ ..add(1951)
+ ..add(1952)
+ ..add(1953)
+ ..add(1954)
+ ..add(1955)
+ ..add(1956)
+ ..add(1957)
+ ..add(1958)
+ ..add(1959)
+ ..add(1960)
+ ..add(1961)
+ ..add(1962)
+ ..add(1963)
+ ..add(1964)
+ ..add(1965)
+ ..add(1966)
+ ..add(1967)
+ ..add(1968)
+ ..add(1969)
+ ..add(1970)
+ ..add(1971)
+ ..add(1972)
+ ..add(1973)
+ ..add(1974)
+ ..add(1975)
+ ..add(1976)
+ ..add(1977)
+ ..add(1978)
+ ..add(1979)
+ ..add(1980)
+ ..add(1981)
+ ..add(1982)
+ ..add(1983)
+ ..add(1984)
+ ..add(1985)
+ ..add(1986)
+ ..add(1987)
+ ..add(1988)
+ ..add(1989)
+ ..add(1990)
+ ..add(1991)
+ ..add(1992)
+ ..add(1993)
+ ..add(1994)
+ ..add(1995)
+ ..add(1996)
+ ..add(1997)
+ ..add(1998)
+ ..add(1999)
+ ..add(2000)
+ ..add(2001)
+ ..add(2002)
+ ..add(2003)
+ ..add(2004)
+ ..add(2005)
+ ..add(2006)
+ ..add(2007)
+ ..add(2008)
+ ..add(2009)
+ ..add(2010)
+ ..add(2011)
+ ..add(2012)
+ ..add(2013)
+ ..add(2014)
+ ..add(2015)
+ ..add(2016)
+ ..add(2017)
+ ..add(2018)
+ ..add(2019)
+ ..add(2020)
+ ..add(2021)
+ ..add(2022)
+ ..add(2023)
+ ..add(2024)
+ ..add(2025)
+ ..add(2026)
+ ..add(2027)
+ ..add(2028)
+ ..add(2029)
+ ..add(2030)
+ ..add(2031)
+ ..add(2032)
+ ..add(2033)
+ ..add(2034)
+ ..add(2035)
+ ..add(2036)
+ ..add(2037)
+ ..add(2038)
+ ..add(2039)
+ ..add(2040)
+ ..add(2041)
+ ..add(2042)
+ ..add(2043)
+ ..add(2044)
+ ..add(2045)
+ ..add(2046)
+ ..add(2047)
+ ..add(2048)
+ ..add(2049)
+ ..add(2050)
+ ..add(2051)
+ ..add(2052)
+ ..add(2053)
+ ..add(2054)
+ ..add(2055)
+ ..add(2056)
+ ..add(2057)
+ ..add(2058)
+ ..add(2059)
+ ..add(2060)
+ ..add(2061)
+ ..add(2062)
+ ..add(2063)
+ ..add(2064)
+ ..add(2065)
+ ..add(2066)
+ ..add(2067)
+ ..add(2068)
+ ..add(2069)
+ ..add(2070)
+ ..add(2071)
+ ..add(2072)
+ ..add(2073)
+ ..add(2074)
+ ..add(2075)
+ ..add(2076)
+ ..add(2077)
+ ..add(2078)
+ ..add(2079)
+ ..add(2080)
+ ..add(2081)
+ ..add(2082)
+ ..add(2083)
+ ..add(2084)
+ ..add(2085)
+ ..add(2086)
+ ..add(2087)
+ ..add(2088)
+ ..add(2089)
+ ..add(2090)
+ ..add(2091)
+ ..add(2092)
+ ..add(2093)
+ ..add(2094)
+ ..add(2095)
+ ..add(2096)
+ ..add(2097)
+ ..add(2098)
+ ..add(2099)
+ ..add(2100)
+ ..add(2101)
+ ..add(2102)
+ ..add(2103)
+ ..add(2104)
+ ..add(2105)
+ ..add(2106)
+ ..add(2107)
+ ..add(2108)
+ ..add(2109)
+ ..add(2110)
+ ..add(2111)
+ ..add(2112)
+ ..add(2113)
+ ..add(2114)
+ ..add(2115)
+ ..add(2116)
+ ..add(2117)
+ ..add(2118)
+ ..add(2119)
+ ..add(2120)
+ ..add(2121)
+ ..add(2122)
+ ..add(2123)
+ ..add(2124)
+ ..add(2125)
+ ..add(2126)
+ ..add(2127)
+ ..add(2128)
+ ..add(2129)
+ ..add(2130)
+ ..add(2131)
+ ..add(2132)
+ ..add(2133)
+ ..add(2134)
+ ..add(2135)
+ ..add(2136)
+ ..add(2137)
+ ..add(2138)
+ ..add(2139)
+ ..add(2140)
+ ..add(2141)
+ ..add(2142)
+ ..add(2143)
+ ..add(2144)
+ ..add(2145)
+ ..add(2146)
+ ..add(2147)
+ ..add(2148)
+ ..add(2149)
+ ..add(2150)
+ ..add(2151)
+ ..add(2152)
+ ..add(2153)
+ ..add(2154)
+ ..add(2155)
+ ..add(2156)
+ ..add(2157)
+ ..add(2158)
+ ..add(2159)
+ ..add(2160)
+ ..add(2161)
+ ..add(2162)
+ ..add(2163)
+ ..add(2164)
+ ..add(2165)
+ ..add(2166)
+ ..add(2167)
+ ..add(2168)
+ ..add(2169)
+ ..add(2170)
+ ..add(2171)
+ ..add(2172)
+ ..add(2173)
+ ..add(2174)
+ ..add(2175)
+ ..add(2176)
+ ..add(2177)
+ ..add(2178)
+ ..add(2179)
+ ..add(2180)
+ ..add(2181)
+ ..add(2182)
+ ..add(2183)
+ ..add(2184)
+ ..add(2185)
+ ..add(2186)
+ ..add(2187)
+ ..add(2188)
+ ..add(2189)
+ ..add(2190)
+ ..add(2191)
+ ..add(2192)
+ ..add(2193)
+ ..add(2194)
+ ..add(2195)
+ ..add(2196)
+ ..add(2197)
+ ..add(2198)
+ ..add(2199)
+ ..add(2200)
+ ..add(2201)
+ ..add(2202)
+ ..add(2203)
+ ..add(2204)
+ ..add(2205)
+ ..add(2206)
+ ..add(2207)
+ ..add(2208)
+ ..add(2209)
+ ..add(2210)
+ ..add(2211)
+ ..add(2212)
+ ..add(2213)
+ ..add(2214)
+ ..add(2215)
+ ..add(2216)
+ ..add(2217)
+ ..add(2218)
+ ..add(2219)
+ ..add(2220)
+ ..add(2221)
+ ..add(2222)
+ ..add(2223)
+ ..add(2224)
+ ..add(2225)
+ ..add(2226)
+ ..add(2227)
+ ..add(2228)
+ ..add(2229)
+ ..add(2230)
+ ..add(2231)
+ ..add(2232)
+ ..add(2233)
+ ..add(2234)
+ ..add(2235)
+ ..add(2236)
+ ..add(2237)
+ ..add(2238)
+ ..add(2239)
+ ..add(2240)
+ ..add(2241)
+ ..add(2242)
+ ..add(2243)
+ ..add(2244)
+ ..add(2245)
+ ..add(2246)
+ ..add(2247)
+ ..add(2248)
+ ..add(2249)
+ ..add(2250)
+ ..add(2251)
+ ..add(2252)
+ ..add(2253)
+ ..add(2254)
+ ..add(2255)
+ ..add(2256)
+ ..add(2257)
+ ..add(2258)
+ ..add(2259)
+ ..add(2260)
+ ..add(2261)
+ ..add(2262)
+ ..add(2263)
+ ..add(2264)
+ ..add(2265)
+ ..add(2266)
+ ..add(2267)
+ ..add(2268)
+ ..add(2269)
+ ..add(2270)
+ ..add(2271)
+ ..add(2272)
+ ..add(2273)
+ ..add(2274)
+ ..add(2275)
+ ..add(2276)
+ ..add(2277)
+ ..add(2278)
+ ..add(2279)
+ ..add(2280)
+ ..add(2281)
+ ..add(2282)
+ ..add(2283)
+ ..add(2284)
+ ..add(2285)
+ ..add(2286)
+ ..add(2287)
+ ..add(2288)
+ ..add(2289)
+ ..add(2290)
+ ..add(2291)
+ ..add(2292)
+ ..add(2293)
+ ..add(2294)
+ ..add(2295)
+ ..add(2296)
+ ..add(2297)
+ ..add(2298)
+ ..add(2299)
+ ..add(2300)
+ ..add(2301)
+ ..add(2302)
+ ..add(2303)
+ ..add(2304)
+ ..add(2305)
+ ..add(2306)
+ ..add(2307)
+ ..add(2308)
+ ..add(2309)
+ ..add(2310)
+ ..add(2311)
+ ..add(2312)
+ ..add(2313)
+ ..add(2314)
+ ..add(2315)
+ ..add(2316)
+ ..add(2317)
+ ..add(2318)
+ ..add(2319)
+ ..add(2320)
+ ..add(2321)
+ ..add(2322)
+ ..add(2323)
+ ..add(2324)
+ ..add(2325)
+ ..add(2326)
+ ..add(2327)
+ ..add(2328)
+ ..add(2329)
+ ..add(2330)
+ ..add(2331)
+ ..add(2332)
+ ..add(2333)
+ ..add(2334)
+ ..add(2335)
+ ..add(2336)
+ ..add(2337)
+ ..add(2338)
+ ..add(2339)
+ ..add(2340)
+ ..add(2341)
+ ..add(2342)
+ ..add(2343)
+ ..add(2344)
+ ..add(2345)
+ ..add(2346)
+ ..add(2347)
+ ..add(2348)
+ ..add(2349)
+ ..add(2350)
+ ..add(2351)
+ ..add(2352)
+ ..add(2353)
+ ..add(2354)
+ ..add(2355)
+ ..add(2356)
+ ..add(2357)
+ ..add(2358)
+ ..add(2359)
+ ..add(2360)
+ ..add(2361)
+ ..add(2362)
+ ..add(2363)
+ ..add(2364)
+ ..add(2365)
+ ..add(2366)
+ ..add(2367)
+ ..add(2368)
+ ..add(2369)
+ ..add(2370)
+ ..add(2371)
+ ..add(2372)
+ ..add(2373)
+ ..add(2374)
+ ..add(2375)
+ ..add(2376)
+ ..add(2377)
+ ..add(2378)
+ ..add(2379)
+ ..add(2380)
+ ..add(2381)
+ ..add(2382)
+ ..add(2383)
+ ..add(2384)
+ ..add(2385)
+ ..add(2386)
+ ..add(2387)
+ ..add(2388)
+ ..add(2389)
+ ..add(2390)
+ ..add(2391)
+ ..add(2392)
+ ..add(2393)
+ ..add(2394)
+ ..add(2395)
+ ..add(2396)
+ ..add(2397)
+ ..add(2398)
+ ..add(2399)
+ ..add(2400)
+ ..add(2401)
+ ..add(2402)
+ ..add(2403)
+ ..add(2404)
+ ..add(2405)
+ ..add(2406)
+ ..add(2407)
+ ..add(2408)
+ ..add(2409)
+ ..add(2410)
+ ..add(2411)
+ ..add(2412)
+ ..add(2413)
+ ..add(2414)
+ ..add(2415)
+ ..add(2416)
+ ..add(2417)
+ ..add(2418)
+ ..add(2419)
+ ..add(2420)
+ ..add(2421)
+ ..add(2422)
+ ..add(2423)
+ ..add(2424)
+ ..add(2425)
+ ..add(2426)
+ ..add(2427)
+ ..add(2428)
+ ..add(2429)
+ ..add(2430)
+ ..add(2431)
+ ..add(2432)
+ ..add(2433)
+ ..add(2434)
+ ..add(2435)
+ ..add(2436)
+ ..add(2437)
+ ..add(2438)
+ ..add(2439)
+ ..add(2440)
+ ..add(2441)
+ ..add(2442)
+ ..add(2443)
+ ..add(2444)
+ ..add(2445)
+ ..add(2446)
+ ..add(2447)
+ ..add(2448)
+ ..add(2449)
+ ..add(2450)
+ ..add(2451)
+ ..add(2452)
+ ..add(2453)
+ ..add(2454)
+ ..add(2455)
+ ..add(2456)
+ ..add(2457)
+ ..add(2458)
+ ..add(2459)
+ ..add(2460)
+ ..add(2461)
+ ..add(2462)
+ ..add(2463)
+ ..add(2464)
+ ..add(2465)
+ ..add(2466)
+ ..add(2467)
+ ..add(2468)
+ ..add(2469)
+ ..add(2470)
+ ..add(2471)
+ ..add(2472)
+ ..add(2473)
+ ..add(2474)
+ ..add(2475)
+ ..add(2476)
+ ..add(2477)
+ ..add(2478)
+ ..add(2479)
+ ..add(2480)
+ ..add(2481)
+ ..add(2482)
+ ..add(2483)
+ ..add(2484)
+ ..add(2485)
+ ..add(2486)
+ ..add(2487)
+ ..add(2488)
+ ..add(2489)
+ ..add(2490)
+ ..add(2491)
+ ..add(2492)
+ ..add(2493)
+ ..add(2494)
+ ..add(2495)
+ ..add(2496)
+ ..add(2497)
+ ..add(2498)
+ ..add(2499)
+ ..add(2500)
+ ..add(2501)
+ ..add(2502)
+ ..add(2503)
+ ..add(2504)
+ ..add(2505)
+ ..add(2506)
+ ..add(2507)
+ ..add(2508)
+ ..add(2509)
+ ..add(2510)
+ ..add(2511)
+ ..add(2512)
+ ..add(2513)
+ ..add(2514)
+ ..add(2515)
+ ..add(2516)
+ ..add(2517)
+ ..add(2518)
+ ..add(2519)
+ ..add(2520)
+ ..add(2521)
+ ..add(2522)
+ ..add(2523)
+ ..add(2524)
+ ..add(2525)
+ ..add(2526)
+ ..add(2527)
+ ..add(2528)
+ ..add(2529)
+ ..add(2530)
+ ..add(2531)
+ ..add(2532)
+ ..add(2533)
+ ..add(2534)
+ ..add(2535)
+ ..add(2536)
+ ..add(2537)
+ ..add(2538)
+ ..add(2539)
+ ..add(2540)
+ ..add(2541)
+ ..add(2542)
+ ..add(2543)
+ ..add(2544)
+ ..add(2545)
+ ..add(2546)
+ ..add(2547)
+ ..add(2548)
+ ..add(2549)
+ ..add(2550)
+ ..add(2551)
+ ..add(2552)
+ ..add(2553)
+ ..add(2554)
+ ..add(2555)
+ ..add(2556)
+ ..add(2557)
+ ..add(2558)
+ ..add(2559)
+ ..add(2560)
+ ..add(2561)
+ ..add(2562)
+ ..add(2563)
+ ..add(2564)
+ ..add(2565)
+ ..add(2566)
+ ..add(2567)
+ ..add(2568)
+ ..add(2569)
+ ..add(2570)
+ ..add(2571)
+ ..add(2572)
+ ..add(2573)
+ ..add(2574)
+ ..add(2575)
+ ..add(2576)
+ ..add(2577)
+ ..add(2578)
+ ..add(2579)
+ ..add(2580)
+ ..add(2581)
+ ..add(2582)
+ ..add(2583)
+ ..add(2584)
+ ..add(2585)
+ ..add(2586)
+ ..add(2587)
+ ..add(2588)
+ ..add(2589)
+ ..add(2590)
+ ..add(2591)
+ ..add(2592)
+ ..add(2593)
+ ..add(2594)
+ ..add(2595)
+ ..add(2596)
+ ..add(2597)
+ ..add(2598)
+ ..add(2599)
+ ..add(2600)
+ ..add(2601)
+ ..add(2602)
+ ..add(2603)
+ ..add(2604)
+ ..add(2605)
+ ..add(2606)
+ ..add(2607)
+ ..add(2608)
+ ..add(2609)
+ ..add(2610)
+ ..add(2611)
+ ..add(2612)
+ ..add(2613)
+ ..add(2614)
+ ..add(2615)
+ ..add(2616)
+ ..add(2617)
+ ..add(2618)
+ ..add(2619)
+ ..add(2620)
+ ..add(2621)
+ ..add(2622)
+ ..add(2623)
+ ..add(2624)
+ ..add(2625)
+ ..add(2626)
+ ..add(2627)
+ ..add(2628)
+ ..add(2629)
+ ..add(2630)
+ ..add(2631)
+ ..add(2632)
+ ..add(2633)
+ ..add(2634)
+ ..add(2635)
+ ..add(2636)
+ ..add(2637)
+ ..add(2638)
+ ..add(2639)
+ ..add(2640)
+ ..add(2641)
+ ..add(2642)
+ ..add(2643)
+ ..add(2644)
+ ..add(2645)
+ ..add(2646)
+ ..add(2647)
+ ..add(2648)
+ ..add(2649)
+ ..add(2650)
+ ..add(2651)
+ ..add(2652)
+ ..add(2653)
+ ..add(2654)
+ ..add(2655)
+ ..add(2656)
+ ..add(2657)
+ ..add(2658)
+ ..add(2659)
+ ..add(2660)
+ ..add(2661)
+ ..add(2662)
+ ..add(2663)
+ ..add(2664)
+ ..add(2665)
+ ..add(2666)
+ ..add(2667)
+ ..add(2668)
+ ..add(2669)
+ ..add(2670)
+ ..add(2671)
+ ..add(2672)
+ ..add(2673)
+ ..add(2674)
+ ..add(2675)
+ ..add(2676)
+ ..add(2677)
+ ..add(2678)
+ ..add(2679)
+ ..add(2680)
+ ..add(2681)
+ ..add(2682)
+ ..add(2683)
+ ..add(2684)
+ ..add(2685)
+ ..add(2686)
+ ..add(2687)
+ ..add(2688)
+ ..add(2689)
+ ..add(2690)
+ ..add(2691)
+ ..add(2692)
+ ..add(2693)
+ ..add(2694)
+ ..add(2695)
+ ..add(2696)
+ ..add(2697)
+ ..add(2698)
+ ..add(2699)
+ ..add(2700)
+ ..add(2701)
+ ..add(2702)
+ ..add(2703)
+ ..add(2704)
+ ..add(2705)
+ ..add(2706)
+ ..add(2707)
+ ..add(2708)
+ ..add(2709)
+ ..add(2710)
+ ..add(2711)
+ ..add(2712)
+ ..add(2713)
+ ..add(2714)
+ ..add(2715)
+ ..add(2716)
+ ..add(2717)
+ ..add(2718)
+ ..add(2719)
+ ..add(2720)
+ ..add(2721)
+ ..add(2722)
+ ..add(2723)
+ ..add(2724)
+ ..add(2725)
+ ..add(2726)
+ ..add(2727)
+ ..add(2728)
+ ..add(2729)
+ ..add(2730)
+ ..add(2731)
+ ..add(2732)
+ ..add(2733)
+ ..add(2734)
+ ..add(2735)
+ ..add(2736)
+ ..add(2737)
+ ..add(2738)
+ ..add(2739)
+ ..add(2740)
+ ..add(2741)
+ ..add(2742)
+ ..add(2743)
+ ..add(2744)
+ ..add(2745)
+ ..add(2746)
+ ..add(2747)
+ ..add(2748)
+ ..add(2749)
+ ..add(2750)
+ ..add(2751)
+ ..add(2752)
+ ..add(2753)
+ ..add(2754)
+ ..add(2755)
+ ..add(2756)
+ ..add(2757)
+ ..add(2758)
+ ..add(2759)
+ ..add(2760)
+ ..add(2761)
+ ..add(2762)
+ ..add(2763)
+ ..add(2764)
+ ..add(2765)
+ ..add(2766)
+ ..add(2767)
+ ..add(2768)
+ ..add(2769)
+ ..add(2770)
+ ..add(2771)
+ ..add(2772)
+ ..add(2773)
+ ..add(2774)
+ ..add(2775)
+ ..add(2776)
+ ..add(2777)
+ ..add(2778)
+ ..add(2779)
+ ..add(2780)
+ ..add(2781)
+ ..add(2782)
+ ..add(2783)
+ ..add(2784)
+ ..add(2785)
+ ..add(2786)
+ ..add(2787)
+ ..add(2788)
+ ..add(2789)
+ ..add(2790)
+ ..add(2791)
+ ..add(2792)
+ ..add(2793)
+ ..add(2794)
+ ..add(2795)
+ ..add(2796)
+ ..add(2797)
+ ..add(2798)
+ ..add(2799)
+ ..add(2800)
+ ..add(2801)
+ ..add(2802)
+ ..add(2803)
+ ..add(2804)
+ ..add(2805)
+ ..add(2806)
+ ..add(2807)
+ ..add(2808)
+ ..add(2809)
+ ..add(2810)
+ ..add(2811)
+ ..add(2812)
+ ..add(2813)
+ ..add(2814)
+ ..add(2815)
+ ..add(2816)
+ ..add(2817)
+ ..add(2818)
+ ..add(2819)
+ ..add(2820)
+ ..add(2821)
+ ..add(2822)
+ ..add(2823)
+ ..add(2824)
+ ..add(2825)
+ ..add(2826)
+ ..add(2827)
+ ..add(2828)
+ ..add(2829)
+ ..add(2830)
+ ..add(2831)
+ ..add(2832)
+ ..add(2833)
+ ..add(2834)
+ ..add(2835)
+ ..add(2836)
+ ..add(2837)
+ ..add(2838)
+ ..add(2839)
+ ..add(2840)
+ ..add(2841)
+ ..add(2842)
+ ..add(2843)
+ ..add(2844)
+ ..add(2845)
+ ..add(2846)
+ ..add(2847)
+ ..add(2848)
+ ..add(2849)
+ ..add(2850)
+ ..add(2851)
+ ..add(2852)
+ ..add(2853)
+ ..add(2854)
+ ..add(2855)
+ ..add(2856)
+ ..add(2857)
+ ..add(2858)
+ ..add(2859)
+ ..add(2860)
+ ..add(2861)
+ ..add(2862)
+ ..add(2863)
+ ..add(2864)
+ ..add(2865)
+ ..add(2866)
+ ..add(2867)
+ ..add(2868)
+ ..add(2869)
+ ..add(2870)
+ ..add(2871)
+ ..add(2872)
+ ..add(2873)
+ ..add(2874)
+ ..add(2875)
+ ..add(2876)
+ ..add(2877)
+ ..add(2878)
+ ..add(2879)
+ ..add(2880)
+ ..add(2881)
+ ..add(2882)
+ ..add(2883)
+ ..add(2884)
+ ..add(2885)
+ ..add(2886)
+ ..add(2887)
+ ..add(2888)
+ ..add(2889)
+ ..add(2890)
+ ..add(2891)
+ ..add(2892)
+ ..add(2893)
+ ..add(2894)
+ ..add(2895)
+ ..add(2896)
+ ..add(2897)
+ ..add(2898)
+ ..add(2899)
+ ..add(2900)
+ ..add(2901)
+ ..add(2902)
+ ..add(2903)
+ ..add(2904)
+ ..add(2905)
+ ..add(2906)
+ ..add(2907)
+ ..add(2908)
+ ..add(2909)
+ ..add(2910)
+ ..add(2911)
+ ..add(2912)
+ ..add(2913)
+ ..add(2914)
+ ..add(2915)
+ ..add(2916)
+ ..add(2917)
+ ..add(2918)
+ ..add(2919)
+ ..add(2920)
+ ..add(2921)
+ ..add(2922)
+ ..add(2923)
+ ..add(2924)
+ ..add(2925)
+ ..add(2926)
+ ..add(2927)
+ ..add(2928)
+ ..add(2929)
+ ..add(2930)
+ ..add(2931)
+ ..add(2932)
+ ..add(2933)
+ ..add(2934)
+ ..add(2935)
+ ..add(2936)
+ ..add(2937)
+ ..add(2938)
+ ..add(2939)
+ ..add(2940)
+ ..add(2941)
+ ..add(2942)
+ ..add(2943)
+ ..add(2944)
+ ..add(2945)
+ ..add(2946)
+ ..add(2947)
+ ..add(2948)
+ ..add(2949)
+ ..add(2950)
+ ..add(2951)
+ ..add(2952)
+ ..add(2953)
+ ..add(2954)
+ ..add(2955)
+ ..add(2956)
+ ..add(2957)
+ ..add(2958)
+ ..add(2959)
+ ..add(2960)
+ ..add(2961)
+ ..add(2962)
+ ..add(2963)
+ ..add(2964)
+ ..add(2965)
+ ..add(2966)
+ ..add(2967)
+ ..add(2968)
+ ..add(2969)
+ ..add(2970)
+ ..add(2971)
+ ..add(2972)
+ ..add(2973)
+ ..add(2974)
+ ..add(2975)
+ ..add(2976)
+ ..add(2977)
+ ..add(2978)
+ ..add(2979)
+ ..add(2980)
+ ..add(2981)
+ ..add(2982)
+ ..add(2983)
+ ..add(2984)
+ ..add(2985)
+ ..add(2986)
+ ..add(2987)
+ ..add(2988)
+ ..add(2989)
+ ..add(2990)
+ ..add(2991)
+ ..add(2992)
+ ..add(2993)
+ ..add(2994)
+ ..add(2995)
+ ..add(2996)
+ ..add(2997)
+ ..add(2998)
+ ..add(2999)
+ ..add(3000)
+ ..add(3001)
+ ..add(3002)
+ ..add(3003)
+ ..add(3004)
+ ..add(3005)
+ ..add(3006)
+ ..add(3007)
+ ..add(3008)
+ ..add(3009)
+ ..add(3010)
+ ..add(3011)
+ ..add(3012)
+ ..add(3013)
+ ..add(3014)
+ ..add(3015)
+ ..add(3016)
+ ..add(3017)
+ ..add(3018)
+ ..add(3019)
+ ..add(3020)
+ ..add(3021)
+ ..add(3022)
+ ..add(3023)
+ ..add(3024)
+ ..add(3025)
+ ..add(3026)
+ ..add(3027)
+ ..add(3028)
+ ..add(3029)
+ ..add(3030)
+ ..add(3031)
+ ..add(3032)
+ ..add(3033)
+ ..add(3034)
+ ..add(3035)
+ ..add(3036)
+ ..add(3037)
+ ..add(3038)
+ ..add(3039)
+ ..add(3040)
+ ..add(3041)
+ ..add(3042)
+ ..add(3043)
+ ..add(3044)
+ ..add(3045)
+ ..add(3046)
+ ..add(3047)
+ ..add(3048)
+ ..add(3049)
+ ..add(3050)
+ ..add(3051)
+ ..add(3052)
+ ..add(3053)
+ ..add(3054)
+ ..add(3055)
+ ..add(3056)
+ ..add(3057)
+ ..add(3058)
+ ..add(3059)
+ ..add(3060)
+ ..add(3061)
+ ..add(3062)
+ ..add(3063)
+ ..add(3064)
+ ..add(3065)
+ ..add(3066)
+ ..add(3067)
+ ..add(3068)
+ ..add(3069)
+ ..add(3070)
+ ..add(3071)
+ ..add(3072)
+ ..add(3073)
+ ..add(3074)
+ ..add(3075)
+ ..add(3076)
+ ..add(3077)
+ ..add(3078)
+ ..add(3079)
+ ..add(3080)
+ ..add(3081)
+ ..add(3082)
+ ..add(3083)
+ ..add(3084)
+ ..add(3085)
+ ..add(3086)
+ ..add(3087)
+ ..add(3088)
+ ..add(3089)
+ ..add(3090)
+ ..add(3091)
+ ..add(3092)
+ ..add(3093)
+ ..add(3094)
+ ..add(3095)
+ ..add(3096)
+ ..add(3097)
+ ..add(3098)
+ ..add(3099)
+ ..add(3100)
+ ..add(3101)
+ ..add(3102)
+ ..add(3103)
+ ..add(3104)
+ ..add(3105)
+ ..add(3106)
+ ..add(3107)
+ ..add(3108)
+ ..add(3109)
+ ..add(3110)
+ ..add(3111)
+ ..add(3112)
+ ..add(3113)
+ ..add(3114)
+ ..add(3115)
+ ..add(3116)
+ ..add(3117)
+ ..add(3118)
+ ..add(3119)
+ ..add(3120)
+ ..add(3121)
+ ..add(3122)
+ ..add(3123)
+ ..add(3124)
+ ..add(3125)
+ ..add(3126)
+ ..add(3127)
+ ..add(3128)
+ ..add(3129)
+ ..add(3130)
+ ..add(3131)
+ ..add(3132)
+ ..add(3133)
+ ..add(3134)
+ ..add(3135)
+ ..add(3136)
+ ..add(3137)
+ ..add(3138)
+ ..add(3139)
+ ..add(3140)
+ ..add(3141)
+ ..add(3142)
+ ..add(3143)
+ ..add(3144)
+ ..add(3145)
+ ..add(3146)
+ ..add(3147)
+ ..add(3148)
+ ..add(3149)
+ ..add(3150)
+ ..add(3151)
+ ..add(3152)
+ ..add(3153)
+ ..add(3154)
+ ..add(3155)
+ ..add(3156)
+ ..add(3157)
+ ..add(3158)
+ ..add(3159)
+ ..add(3160)
+ ..add(3161)
+ ..add(3162)
+ ..add(3163)
+ ..add(3164)
+ ..add(3165)
+ ..add(3166)
+ ..add(3167)
+ ..add(3168)
+ ..add(3169)
+ ..add(3170)
+ ..add(3171)
+ ..add(3172)
+ ..add(3173)
+ ..add(3174)
+ ..add(3175)
+ ..add(3176)
+ ..add(3177)
+ ..add(3178)
+ ..add(3179)
+ ..add(3180)
+ ..add(3181)
+ ..add(3182)
+ ..add(3183)
+ ..add(3184)
+ ..add(3185)
+ ..add(3186)
+ ..add(3187)
+ ..add(3188)
+ ..add(3189)
+ ..add(3190)
+ ..add(3191)
+ ..add(3192)
+ ..add(3193)
+ ..add(3194)
+ ..add(3195)
+ ..add(3196)
+ ..add(3197)
+ ..add(3198)
+ ..add(3199)
+ ..add(3200)
+ ..add(3201)
+ ..add(3202)
+ ..add(3203)
+ ..add(3204)
+ ..add(3205)
+ ..add(3206)
+ ..add(3207)
+ ..add(3208)
+ ..add(3209)
+ ..add(3210)
+ ..add(3211)
+ ..add(3212)
+ ..add(3213)
+ ..add(3214)
+ ..add(3215)
+ ..add(3216)
+ ..add(3217)
+ ..add(3218)
+ ..add(3219)
+ ..add(3220)
+ ..add(3221)
+ ..add(3222)
+ ..add(3223)
+ ..add(3224)
+ ..add(3225)
+ ..add(3226)
+ ..add(3227)
+ ..add(3228)
+ ..add(3229)
+ ..add(3230)
+ ..add(3231)
+ ..add(3232)
+ ..add(3233)
+ ..add(3234)
+ ..add(3235)
+ ..add(3236)
+ ..add(3237)
+ ..add(3238)
+ ..add(3239)
+ ..add(3240)
+ ..add(3241)
+ ..add(3242)
+ ..add(3243)
+ ..add(3244)
+ ..add(3245)
+ ..add(3246)
+ ..add(3247)
+ ..add(3248)
+ ..add(3249)
+ ..add(3250)
+ ..add(3251)
+ ..add(3252)
+ ..add(3253)
+ ..add(3254)
+ ..add(3255)
+ ..add(3256)
+ ..add(3257)
+ ..add(3258)
+ ..add(3259)
+ ..add(3260)
+ ..add(3261)
+ ..add(3262)
+ ..add(3263)
+ ..add(3264)
+ ..add(3265)
+ ..add(3266)
+ ..add(3267)
+ ..add(3268)
+ ..add(3269)
+ ..add(3270)
+ ..add(3271)
+ ..add(3272)
+ ..add(3273)
+ ..add(3274)
+ ..add(3275)
+ ..add(3276)
+ ..add(3277)
+ ..add(3278)
+ ..add(3279)
+ ..add(3280)
+ ..add(3281)
+ ..add(3282)
+ ..add(3283)
+ ..add(3284)
+ ..add(3285)
+ ..add(3286)
+ ..add(3287)
+ ..add(3288)
+ ..add(3289)
+ ..add(3290)
+ ..add(3291)
+ ..add(3292)
+ ..add(3293)
+ ..add(3294)
+ ..add(3295)
+ ..add(3296)
+ ..add(3297)
+ ..add(3298)
+ ..add(3299)
+ ..add(3300)
+ ..add(3301)
+ ..add(3302)
+ ..add(3303)
+ ..add(3304)
+ ..add(3305)
+ ..add(3306)
+ ..add(3307)
+ ..add(3308)
+ ..add(3309)
+ ..add(3310)
+ ..add(3311)
+ ..add(3312)
+ ..add(3313)
+ ..add(3314)
+ ..add(3315)
+ ..add(3316)
+ ..add(3317)
+ ..add(3318)
+ ..add(3319)
+ ..add(3320)
+ ..add(3321)
+ ..add(3322)
+ ..add(3323)
+ ..add(3324)
+ ..add(3325)
+ ..add(3326)
+ ..add(3327)
+ ..add(3328)
+ ..add(3329)
+ ..add(3330)
+ ..add(3331)
+ ..add(3332)
+ ..add(3333)
+ ..add(3334)
+ ..add(3335)
+ ..add(3336)
+ ..add(3337)
+ ..add(3338)
+ ..add(3339)
+ ..add(3340)
+ ..add(3341)
+ ..add(3342)
+ ..add(3343)
+ ..add(3344)
+ ..add(3345)
+ ..add(3346)
+ ..add(3347)
+ ..add(3348)
+ ..add(3349)
+ ..add(3350)
+ ..add(3351)
+ ..add(3352)
+ ..add(3353)
+ ..add(3354)
+ ..add(3355)
+ ..add(3356)
+ ..add(3357)
+ ..add(3358)
+ ..add(3359)
+ ..add(3360)
+ ..add(3361)
+ ..add(3362)
+ ..add(3363)
+ ..add(3364)
+ ..add(3365)
+ ..add(3366)
+ ..add(3367)
+ ..add(3368)
+ ..add(3369)
+ ..add(3370)
+ ..add(3371)
+ ..add(3372)
+ ..add(3373)
+ ..add(3374)
+ ..add(3375)
+ ..add(3376)
+ ..add(3377)
+ ..add(3378)
+ ..add(3379)
+ ..add(3380)
+ ..add(3381)
+ ..add(3382)
+ ..add(3383)
+ ..add(3384)
+ ..add(3385)
+ ..add(3386)
+ ..add(3387)
+ ..add(3388)
+ ..add(3389)
+ ..add(3390)
+ ..add(3391)
+ ..add(3392)
+ ..add(3393)
+ ..add(3394)
+ ..add(3395)
+ ..add(3396)
+ ..add(3397)
+ ..add(3398)
+ ..add(3399)
+ ..add(3400)
+ ..add(3401)
+ ..add(3402)
+ ..add(3403)
+ ..add(3404)
+ ..add(3405)
+ ..add(3406)
+ ..add(3407)
+ ..add(3408)
+ ..add(3409)
+ ..add(3410)
+ ..add(3411)
+ ..add(3412)
+ ..add(3413)
+ ..add(3414)
+ ..add(3415)
+ ..add(3416)
+ ..add(3417)
+ ..add(3418)
+ ..add(3419)
+ ..add(3420)
+ ..add(3421)
+ ..add(3422)
+ ..add(3423)
+ ..add(3424)
+ ..add(3425)
+ ..add(3426)
+ ..add(3427)
+ ..add(3428)
+ ..add(3429)
+ ..add(3430)
+ ..add(3431)
+ ..add(3432)
+ ..add(3433)
+ ..add(3434)
+ ..add(3435)
+ ..add(3436)
+ ..add(3437)
+ ..add(3438)
+ ..add(3439)
+ ..add(3440)
+ ..add(3441)
+ ..add(3442)
+ ..add(3443)
+ ..add(3444)
+ ..add(3445)
+ ..add(3446)
+ ..add(3447)
+ ..add(3448)
+ ..add(3449)
+ ..add(3450)
+ ..add(3451)
+ ..add(3452)
+ ..add(3453)
+ ..add(3454)
+ ..add(3455)
+ ..add(3456)
+ ..add(3457)
+ ..add(3458)
+ ..add(3459)
+ ..add(3460)
+ ..add(3461)
+ ..add(3462)
+ ..add(3463)
+ ..add(3464)
+ ..add(3465)
+ ..add(3466)
+ ..add(3467)
+ ..add(3468)
+ ..add(3469)
+ ..add(3470)
+ ..add(3471)
+ ..add(3472)
+ ..add(3473)
+ ..add(3474)
+ ..add(3475)
+ ..add(3476)
+ ..add(3477)
+ ..add(3478)
+ ..add(3479)
+ ..add(3480)
+ ..add(3481)
+ ..add(3482)
+ ..add(3483)
+ ..add(3484)
+ ..add(3485)
+ ..add(3486)
+ ..add(3487)
+ ..add(3488)
+ ..add(3489)
+ ..add(3490)
+ ..add(3491)
+ ..add(3492)
+ ..add(3493)
+ ..add(3494)
+ ..add(3495)
+ ..add(3496)
+ ..add(3497)
+ ..add(3498)
+ ..add(3499)
+ ..add(3500)
+ ..add(3501)
+ ..add(3502)
+ ..add(3503)
+ ..add(3504)
+ ..add(3505)
+ ..add(3506)
+ ..add(3507)
+ ..add(3508)
+ ..add(3509)
+ ..add(3510)
+ ..add(3511)
+ ..add(3512)
+ ..add(3513)
+ ..add(3514)
+ ..add(3515)
+ ..add(3516)
+ ..add(3517)
+ ..add(3518)
+ ..add(3519)
+ ..add(3520)
+ ..add(3521)
+ ..add(3522)
+ ..add(3523)
+ ..add(3524)
+ ..add(3525)
+ ..add(3526)
+ ..add(3527)
+ ..add(3528)
+ ..add(3529)
+ ..add(3530)
+ ..add(3531)
+ ..add(3532)
+ ..add(3533)
+ ..add(3534)
+ ..add(3535)
+ ..add(3536)
+ ..add(3537)
+ ..add(3538)
+ ..add(3539)
+ ..add(3540)
+ ..add(3541)
+ ..add(3542)
+ ..add(3543)
+ ..add(3544)
+ ..add(3545)
+ ..add(3546)
+ ..add(3547)
+ ..add(3548)
+ ..add(3549)
+ ..add(3550)
+ ..add(3551)
+ ..add(3552)
+ ..add(3553)
+ ..add(3554)
+ ..add(3555)
+ ..add(3556)
+ ..add(3557)
+ ..add(3558)
+ ..add(3559)
+ ..add(3560)
+ ..add(3561)
+ ..add(3562)
+ ..add(3563)
+ ..add(3564)
+ ..add(3565)
+ ..add(3566)
+ ..add(3567)
+ ..add(3568)
+ ..add(3569)
+ ..add(3570)
+ ..add(3571)
+ ..add(3572)
+ ..add(3573)
+ ..add(3574)
+ ..add(3575)
+ ..add(3576)
+ ..add(3577)
+ ..add(3578)
+ ..add(3579)
+ ..add(3580)
+ ..add(3581)
+ ..add(3582)
+ ..add(3583)
+ ..add(3584)
+ ..add(3585)
+ ..add(3586)
+ ..add(3587)
+ ..add(3588)
+ ..add(3589)
+ ..add(3590)
+ ..add(3591)
+ ..add(3592)
+ ..add(3593)
+ ..add(3594)
+ ..add(3595)
+ ..add(3596)
+ ..add(3597)
+ ..add(3598)
+ ..add(3599)
+ ..add(3600)
+ ..add(3601)
+ ..add(3602)
+ ..add(3603)
+ ..add(3604)
+ ..add(3605)
+ ..add(3606)
+ ..add(3607)
+ ..add(3608)
+ ..add(3609)
+ ..add(3610)
+ ..add(3611)
+ ..add(3612)
+ ..add(3613)
+ ..add(3614)
+ ..add(3615)
+ ..add(3616)
+ ..add(3617)
+ ..add(3618)
+ ..add(3619)
+ ..add(3620)
+ ..add(3621)
+ ..add(3622)
+ ..add(3623)
+ ..add(3624)
+ ..add(3625)
+ ..add(3626)
+ ..add(3627)
+ ..add(3628)
+ ..add(3629)
+ ..add(3630)
+ ..add(3631)
+ ..add(3632)
+ ..add(3633)
+ ..add(3634)
+ ..add(3635)
+ ..add(3636)
+ ..add(3637)
+ ..add(3638)
+ ..add(3639)
+ ..add(3640)
+ ..add(3641)
+ ..add(3642)
+ ..add(3643)
+ ..add(3644)
+ ..add(3645)
+ ..add(3646)
+ ..add(3647)
+ ..add(3648)
+ ..add(3649)
+ ..add(3650)
+ ..add(3651)
+ ..add(3652)
+ ..add(3653)
+ ..add(3654)
+ ..add(3655)
+ ..add(3656)
+ ..add(3657)
+ ..add(3658)
+ ..add(3659)
+ ..add(3660)
+ ..add(3661)
+ ..add(3662)
+ ..add(3663)
+ ..add(3664)
+ ..add(3665)
+ ..add(3666)
+ ..add(3667)
+ ..add(3668)
+ ..add(3669)
+ ..add(3670)
+ ..add(3671)
+ ..add(3672)
+ ..add(3673)
+ ..add(3674)
+ ..add(3675)
+ ..add(3676)
+ ..add(3677)
+ ..add(3678)
+ ..add(3679)
+ ..add(3680)
+ ..add(3681)
+ ..add(3682)
+ ..add(3683)
+ ..add(3684)
+ ..add(3685)
+ ..add(3686)
+ ..add(3687)
+ ..add(3688)
+ ..add(3689)
+ ..add(3690)
+ ..add(3691)
+ ..add(3692)
+ ..add(3693)
+ ..add(3694)
+ ..add(3695)
+ ..add(3696)
+ ..add(3697)
+ ..add(3698)
+ ..add(3699)
+ ..add(3700)
+ ..add(3701)
+ ..add(3702)
+ ..add(3703)
+ ..add(3704)
+ ..add(3705)
+ ..add(3706)
+ ..add(3707)
+ ..add(3708)
+ ..add(3709)
+ ..add(3710)
+ ..add(3711)
+ ..add(3712)
+ ..add(3713)
+ ..add(3714)
+ ..add(3715)
+ ..add(3716)
+ ..add(3717)
+ ..add(3718)
+ ..add(3719)
+ ..add(3720)
+ ..add(3721)
+ ..add(3722)
+ ..add(3723)
+ ..add(3724)
+ ..add(3725)
+ ..add(3726)
+ ..add(3727)
+ ..add(3728)
+ ..add(3729)
+ ..add(3730)
+ ..add(3731)
+ ..add(3732)
+ ..add(3733)
+ ..add(3734)
+ ..add(3735)
+ ..add(3736)
+ ..add(3737)
+ ..add(3738)
+ ..add(3739)
+ ..add(3740)
+ ..add(3741)
+ ..add(3742)
+ ..add(3743)
+ ..add(3744)
+ ..add(3745)
+ ..add(3746)
+ ..add(3747)
+ ..add(3748)
+ ..add(3749)
+ ..add(3750)
+ ..add(3751)
+ ..add(3752)
+ ..add(3753)
+ ..add(3754)
+ ..add(3755)
+ ..add(3756)
+ ..add(3757)
+ ..add(3758)
+ ..add(3759)
+ ..add(3760)
+ ..add(3761)
+ ..add(3762)
+ ..add(3763)
+ ..add(3764)
+ ..add(3765)
+ ..add(3766)
+ ..add(3767)
+ ..add(3768)
+ ..add(3769)
+ ..add(3770)
+ ..add(3771)
+ ..add(3772)
+ ..add(3773)
+ ..add(3774)
+ ..add(3775)
+ ..add(3776)
+ ..add(3777)
+ ..add(3778)
+ ..add(3779)
+ ..add(3780)
+ ..add(3781)
+ ..add(3782)
+ ..add(3783)
+ ..add(3784)
+ ..add(3785)
+ ..add(3786)
+ ..add(3787)
+ ..add(3788)
+ ..add(3789)
+ ..add(3790)
+ ..add(3791)
+ ..add(3792)
+ ..add(3793)
+ ..add(3794)
+ ..add(3795)
+ ..add(3796)
+ ..add(3797)
+ ..add(3798)
+ ..add(3799)
+ ..add(3800)
+ ..add(3801)
+ ..add(3802)
+ ..add(3803)
+ ..add(3804)
+ ..add(3805)
+ ..add(3806)
+ ..add(3807)
+ ..add(3808)
+ ..add(3809)
+ ..add(3810)
+ ..add(3811)
+ ..add(3812)
+ ..add(3813)
+ ..add(3814)
+ ..add(3815)
+ ..add(3816)
+ ..add(3817)
+ ..add(3818)
+ ..add(3819)
+ ..add(3820)
+ ..add(3821)
+ ..add(3822)
+ ..add(3823)
+ ..add(3824)
+ ..add(3825)
+ ..add(3826)
+ ..add(3827)
+ ..add(3828)
+ ..add(3829)
+ ..add(3830)
+ ..add(3831)
+ ..add(3832)
+ ..add(3833)
+ ..add(3834)
+ ..add(3835)
+ ..add(3836)
+ ..add(3837)
+ ..add(3838)
+ ..add(3839)
+ ..add(3840)
+ ..add(3841)
+ ..add(3842)
+ ..add(3843)
+ ..add(3844)
+ ..add(3845)
+ ..add(3846)
+ ..add(3847)
+ ..add(3848)
+ ..add(3849)
+ ..add(3850)
+ ..add(3851)
+ ..add(3852)
+ ..add(3853)
+ ..add(3854)
+ ..add(3855)
+ ..add(3856)
+ ..add(3857)
+ ..add(3858)
+ ..add(3859)
+ ..add(3860)
+ ..add(3861)
+ ..add(3862)
+ ..add(3863)
+ ..add(3864)
+ ..add(3865)
+ ..add(3866)
+ ..add(3867)
+ ..add(3868)
+ ..add(3869)
+ ..add(3870)
+ ..add(3871)
+ ..add(3872)
+ ..add(3873)
+ ..add(3874)
+ ..add(3875)
+ ..add(3876)
+ ..add(3877)
+ ..add(3878)
+ ..add(3879)
+ ..add(3880)
+ ..add(3881)
+ ..add(3882)
+ ..add(3883)
+ ..add(3884)
+ ..add(3885)
+ ..add(3886)
+ ..add(3887)
+ ..add(3888)
+ ..add(3889)
+ ..add(3890)
+ ..add(3891)
+ ..add(3892)
+ ..add(3893)
+ ..add(3894)
+ ..add(3895)
+ ..add(3896)
+ ..add(3897)
+ ..add(3898)
+ ..add(3899)
+ ..add(3900)
+ ..add(3901)
+ ..add(3902)
+ ..add(3903)
+ ..add(3904)
+ ..add(3905)
+ ..add(3906)
+ ..add(3907)
+ ..add(3908)
+ ..add(3909)
+ ..add(3910)
+ ..add(3911)
+ ..add(3912)
+ ..add(3913)
+ ..add(3914)
+ ..add(3915)
+ ..add(3916)
+ ..add(3917)
+ ..add(3918)
+ ..add(3919)
+ ..add(3920)
+ ..add(3921)
+ ..add(3922)
+ ..add(3923)
+ ..add(3924)
+ ..add(3925)
+ ..add(3926)
+ ..add(3927)
+ ..add(3928)
+ ..add(3929)
+ ..add(3930)
+ ..add(3931)
+ ..add(3932)
+ ..add(3933)
+ ..add(3934)
+ ..add(3935)
+ ..add(3936)
+ ..add(3937)
+ ..add(3938)
+ ..add(3939)
+ ..add(3940)
+ ..add(3941)
+ ..add(3942)
+ ..add(3943)
+ ..add(3944)
+ ..add(3945)
+ ..add(3946)
+ ..add(3947)
+ ..add(3948)
+ ..add(3949)
+ ..add(3950)
+ ..add(3951)
+ ..add(3952)
+ ..add(3953)
+ ..add(3954)
+ ..add(3955)
+ ..add(3956)
+ ..add(3957)
+ ..add(3958)
+ ..add(3959)
+ ..add(3960)
+ ..add(3961)
+ ..add(3962)
+ ..add(3963)
+ ..add(3964)
+ ..add(3965)
+ ..add(3966)
+ ..add(3967)
+ ..add(3968)
+ ..add(3969)
+ ..add(3970)
+ ..add(3971)
+ ..add(3972)
+ ..add(3973)
+ ..add(3974)
+ ..add(3975)
+ ..add(3976)
+ ..add(3977)
+ ..add(3978)
+ ..add(3979)
+ ..add(3980)
+ ..add(3981)
+ ..add(3982)
+ ..add(3983)
+ ..add(3984)
+ ..add(3985)
+ ..add(3986)
+ ..add(3987)
+ ..add(3988)
+ ..add(3989)
+ ..add(3990)
+ ..add(3991)
+ ..add(3992)
+ ..add(3993)
+ ..add(3994)
+ ..add(3995)
+ ..add(3996)
+ ..add(3997)
+ ..add(3998)
+ ..add(3999)
+ ..add(4000)
+ ..add(4001)
+ ..add(4002)
+ ..add(4003)
+ ..add(4004)
+ ..add(4005)
+ ..add(4006)
+ ..add(4007)
+ ..add(4008)
+ ..add(4009)
+ ..add(4010)
+ ..add(4011)
+ ..add(4012)
+ ..add(4013)
+ ..add(4014)
+ ..add(4015)
+ ..add(4016)
+ ..add(4017)
+ ..add(4018)
+ ..add(4019)
+ ..add(4020)
+ ..add(4021)
+ ..add(4022)
+ ..add(4023)
+ ..add(4024)
+ ..add(4025)
+ ..add(4026)
+ ..add(4027)
+ ..add(4028)
+ ..add(4029)
+ ..add(4030)
+ ..add(4031)
+ ..add(4032)
+ ..add(4033)
+ ..add(4034)
+ ..add(4035)
+ ..add(4036)
+ ..add(4037)
+ ..add(4038)
+ ..add(4039)
+ ..add(4040)
+ ..add(4041)
+ ..add(4042)
+ ..add(4043)
+ ..add(4044)
+ ..add(4045)
+ ..add(4046)
+ ..add(4047)
+ ..add(4048)
+ ..add(4049)
+ ..add(4050)
+ ..add(4051)
+ ..add(4052)
+ ..add(4053)
+ ..add(4054)
+ ..add(4055)
+ ..add(4056)
+ ..add(4057)
+ ..add(4058)
+ ..add(4059)
+ ..add(4060)
+ ..add(4061)
+ ..add(4062)
+ ..add(4063)
+ ..add(4064)
+ ..add(4065)
+ ..add(4066)
+ ..add(4067)
+ ..add(4068)
+ ..add(4069)
+ ..add(4070)
+ ..add(4071)
+ ..add(4072)
+ ..add(4073)
+ ..add(4074)
+ ..add(4075)
+ ..add(4076)
+ ..add(4077)
+ ..add(4078)
+ ..add(4079)
+ ..add(4080)
+ ..add(4081)
+ ..add(4082)
+ ..add(4083)
+ ..add(4084)
+ ..add(4085)
+ ..add(4086)
+ ..add(4087)
+ ..add(4088)
+ ..add(4089)
+ ..add(4090)
+ ..add(4091)
+ ..add(4092)
+ ..add(4093)
+ ..add(4094)
+ ..add(4095)
+ ..add(4096)
+ ..add(4097)
+ ..add(4098)
+ ..add(4099)
+ ..add(4100)
+ ..add(4101)
+ ..add(4102)
+ ..add(4103)
+ ..add(4104)
+ ..add(4105)
+ ..add(4106)
+ ..add(4107)
+ ..add(4108)
+ ..add(4109)
+ ..add(4110)
+ ..add(4111)
+ ..add(4112)
+ ..add(4113)
+ ..add(4114)
+ ..add(4115)
+ ..add(4116)
+ ..add(4117)
+ ..add(4118)
+ ..add(4119)
+ ..add(4120)
+ ..add(4121)
+ ..add(4122)
+ ..add(4123)
+ ..add(4124)
+ ..add(4125)
+ ..add(4126)
+ ..add(4127)
+ ..add(4128)
+ ..add(4129)
+ ..add(4130)
+ ..add(4131)
+ ..add(4132)
+ ..add(4133)
+ ..add(4134)
+ ..add(4135)
+ ..add(4136)
+ ..add(4137)
+ ..add(4138)
+ ..add(4139)
+ ..add(4140)
+ ..add(4141)
+ ..add(4142)
+ ..add(4143)
+ ..add(4144)
+ ..add(4145)
+ ..add(4146)
+ ..add(4147)
+ ..add(4148)
+ ..add(4149)
+ ..add(4150)
+ ..add(4151)
+ ..add(4152)
+ ..add(4153)
+ ..add(4154)
+ ..add(4155)
+ ..add(4156)
+ ..add(4157)
+ ..add(4158)
+ ..add(4159)
+ ..add(4160)
+ ..add(4161)
+ ..add(4162)
+ ..add(4163)
+ ..add(4164)
+ ..add(4165)
+ ..add(4166)
+ ..add(4167)
+ ..add(4168)
+ ..add(4169)
+ ..add(4170)
+ ..add(4171)
+ ..add(4172)
+ ..add(4173)
+ ..add(4174)
+ ..add(4175)
+ ..add(4176)
+ ..add(4177)
+ ..add(4178)
+ ..add(4179)
+ ..add(4180)
+ ..add(4181)
+ ..add(4182)
+ ..add(4183)
+ ..add(4184)
+ ..add(4185)
+ ..add(4186)
+ ..add(4187)
+ ..add(4188)
+ ..add(4189)
+ ..add(4190)
+ ..add(4191)
+ ..add(4192)
+ ..add(4193)
+ ..add(4194)
+ ..add(4195)
+ ..add(4196)
+ ..add(4197)
+ ..add(4198)
+ ..add(4199)
+ ..add(4200)
+ ..add(4201)
+ ..add(4202)
+ ..add(4203)
+ ..add(4204)
+ ..add(4205)
+ ..add(4206)
+ ..add(4207)
+ ..add(4208)
+ ..add(4209)
+ ..add(4210)
+ ..add(4211)
+ ..add(4212)
+ ..add(4213)
+ ..add(4214)
+ ..add(4215)
+ ..add(4216)
+ ..add(4217)
+ ..add(4218)
+ ..add(4219)
+ ..add(4220)
+ ..add(4221)
+ ..add(4222)
+ ..add(4223)
+ ..add(4224)
+ ..add(4225)
+ ..add(4226)
+ ..add(4227)
+ ..add(4228)
+ ..add(4229)
+ ..add(4230)
+ ..add(4231)
+ ..add(4232)
+ ..add(4233)
+ ..add(4234)
+ ..add(4235)
+ ..add(4236)
+ ..add(4237)
+ ..add(4238)
+ ..add(4239)
+ ..add(4240)
+ ..add(4241)
+ ..add(4242)
+ ..add(4243)
+ ..add(4244)
+ ..add(4245)
+ ..add(4246)
+ ..add(4247)
+ ..add(4248)
+ ..add(4249)
+ ..add(4250)
+ ..add(4251)
+ ..add(4252)
+ ..add(4253)
+ ..add(4254)
+ ..add(4255)
+ ..add(4256)
+ ..add(4257)
+ ..add(4258)
+ ..add(4259)
+ ..add(4260)
+ ..add(4261)
+ ..add(4262)
+ ..add(4263)
+ ..add(4264)
+ ..add(4265)
+ ..add(4266)
+ ..add(4267)
+ ..add(4268)
+ ..add(4269)
+ ..add(4270)
+ ..add(4271)
+ ..add(4272)
+ ..add(4273)
+ ..add(4274)
+ ..add(4275)
+ ..add(4276)
+ ..add(4277)
+ ..add(4278)
+ ..add(4279)
+ ..add(4280)
+ ..add(4281)
+ ..add(4282)
+ ..add(4283)
+ ..add(4284)
+ ..add(4285)
+ ..add(4286)
+ ..add(4287)
+ ..add(4288)
+ ..add(4289)
+ ..add(4290)
+ ..add(4291)
+ ..add(4292)
+ ..add(4293)
+ ..add(4294)
+ ..add(4295)
+ ..add(4296)
+ ..add(4297)
+ ..add(4298)
+ ..add(4299)
+ ..add(4300)
+ ..add(4301)
+ ..add(4302)
+ ..add(4303)
+ ..add(4304)
+ ..add(4305)
+ ..add(4306)
+ ..add(4307)
+ ..add(4308)
+ ..add(4309)
+ ..add(4310)
+ ..add(4311)
+ ..add(4312)
+ ..add(4313)
+ ..add(4314)
+ ..add(4315)
+ ..add(4316)
+ ..add(4317)
+ ..add(4318)
+ ..add(4319)
+ ..add(4320)
+ ..add(4321)
+ ..add(4322)
+ ..add(4323)
+ ..add(4324)
+ ..add(4325)
+ ..add(4326)
+ ..add(4327)
+ ..add(4328)
+ ..add(4329)
+ ..add(4330)
+ ..add(4331)
+ ..add(4332)
+ ..add(4333)
+ ..add(4334)
+ ..add(4335)
+ ..add(4336)
+ ..add(4337)
+ ..add(4338)
+ ..add(4339)
+ ..add(4340)
+ ..add(4341)
+ ..add(4342)
+ ..add(4343)
+ ..add(4344)
+ ..add(4345)
+ ..add(4346)
+ ..add(4347)
+ ..add(4348)
+ ..add(4349)
+ ..add(4350)
+ ..add(4351)
+ ..add(4352)
+ ..add(4353)
+ ..add(4354)
+ ..add(4355)
+ ..add(4356)
+ ..add(4357)
+ ..add(4358)
+ ..add(4359)
+ ..add(4360)
+ ..add(4361)
+ ..add(4362)
+ ..add(4363)
+ ..add(4364)
+ ..add(4365)
+ ..add(4366)
+ ..add(4367)
+ ..add(4368)
+ ..add(4369)
+ ..add(4370)
+ ..add(4371)
+ ..add(4372)
+ ..add(4373)
+ ..add(4374)
+ ..add(4375)
+ ..add(4376)
+ ..add(4377)
+ ..add(4378)
+ ..add(4379)
+ ..add(4380)
+ ..add(4381)
+ ..add(4382)
+ ..add(4383)
+ ..add(4384)
+ ..add(4385)
+ ..add(4386)
+ ..add(4387)
+ ..add(4388)
+ ..add(4389)
+ ..add(4390)
+ ..add(4391)
+ ..add(4392)
+ ..add(4393)
+ ..add(4394)
+ ..add(4395)
+ ..add(4396)
+ ..add(4397)
+ ..add(4398)
+ ..add(4399)
+ ..add(4400)
+ ..add(4401)
+ ..add(4402)
+ ..add(4403)
+ ..add(4404)
+ ..add(4405)
+ ..add(4406)
+ ..add(4407)
+ ..add(4408)
+ ..add(4409)
+ ..add(4410)
+ ..add(4411)
+ ..add(4412)
+ ..add(4413)
+ ..add(4414)
+ ..add(4415)
+ ..add(4416)
+ ..add(4417)
+ ..add(4418)
+ ..add(4419)
+ ..add(4420)
+ ..add(4421)
+ ..add(4422)
+ ..add(4423)
+ ..add(4424)
+ ..add(4425)
+ ..add(4426)
+ ..add(4427)
+ ..add(4428)
+ ..add(4429)
+ ..add(4430)
+ ..add(4431)
+ ..add(4432)
+ ..add(4433)
+ ..add(4434)
+ ..add(4435)
+ ..add(4436)
+ ..add(4437)
+ ..add(4438)
+ ..add(4439)
+ ..add(4440)
+ ..add(4441)
+ ..add(4442)
+ ..add(4443)
+ ..add(4444)
+ ..add(4445)
+ ..add(4446)
+ ..add(4447)
+ ..add(4448)
+ ..add(4449)
+ ..add(4450)
+ ..add(4451)
+ ..add(4452)
+ ..add(4453)
+ ..add(4454)
+ ..add(4455)
+ ..add(4456)
+ ..add(4457)
+ ..add(4458)
+ ..add(4459)
+ ..add(4460)
+ ..add(4461)
+ ..add(4462)
+ ..add(4463)
+ ..add(4464)
+ ..add(4465)
+ ..add(4466)
+ ..add(4467)
+ ..add(4468)
+ ..add(4469)
+ ..add(4470)
+ ..add(4471)
+ ..add(4472)
+ ..add(4473)
+ ..add(4474)
+ ..add(4475)
+ ..add(4476)
+ ..add(4477)
+ ..add(4478)
+ ..add(4479)
+ ..add(4480)
+ ..add(4481)
+ ..add(4482)
+ ..add(4483)
+ ..add(4484)
+ ..add(4485)
+ ..add(4486)
+ ..add(4487)
+ ..add(4488)
+ ..add(4489)
+ ..add(4490)
+ ..add(4491)
+ ..add(4492)
+ ..add(4493)
+ ..add(4494)
+ ..add(4495)
+ ..add(4496)
+ ..add(4497)
+ ..add(4498)
+ ..add(4499)
+ ..add(4500)
+ ..add(4501)
+ ..add(4502)
+ ..add(4503)
+ ..add(4504)
+ ..add(4505)
+ ..add(4506)
+ ..add(4507)
+ ..add(4508)
+ ..add(4509)
+ ..add(4510)
+ ..add(4511)
+ ..add(4512)
+ ..add(4513)
+ ..add(4514)
+ ..add(4515)
+ ..add(4516)
+ ..add(4517)
+ ..add(4518)
+ ..add(4519)
+ ..add(4520)
+ ..add(4521)
+ ..add(4522)
+ ..add(4523)
+ ..add(4524)
+ ..add(4525)
+ ..add(4526)
+ ..add(4527)
+ ..add(4528)
+ ..add(4529)
+ ..add(4530)
+ ..add(4531)
+ ..add(4532)
+ ..add(4533)
+ ..add(4534)
+ ..add(4535)
+ ..add(4536)
+ ..add(4537)
+ ..add(4538)
+ ..add(4539)
+ ..add(4540)
+ ..add(4541)
+ ..add(4542)
+ ..add(4543)
+ ..add(4544)
+ ..add(4545)
+ ..add(4546)
+ ..add(4547)
+ ..add(4548)
+ ..add(4549)
+ ..add(4550)
+ ..add(4551)
+ ..add(4552)
+ ..add(4553)
+ ..add(4554)
+ ..add(4555)
+ ..add(4556)
+ ..add(4557)
+ ..add(4558)
+ ..add(4559)
+ ..add(4560)
+ ..add(4561)
+ ..add(4562)
+ ..add(4563)
+ ..add(4564)
+ ..add(4565)
+ ..add(4566)
+ ..add(4567)
+ ..add(4568)
+ ..add(4569)
+ ..add(4570)
+ ..add(4571)
+ ..add(4572)
+ ..add(4573)
+ ..add(4574)
+ ..add(4575)
+ ..add(4576)
+ ..add(4577)
+ ..add(4578)
+ ..add(4579)
+ ..add(4580)
+ ..add(4581)
+ ..add(4582)
+ ..add(4583)
+ ..add(4584)
+ ..add(4585)
+ ..add(4586)
+ ..add(4587)
+ ..add(4588)
+ ..add(4589)
+ ..add(4590)
+ ..add(4591)
+ ..add(4592)
+ ..add(4593)
+ ..add(4594)
+ ..add(4595)
+ ..add(4596)
+ ..add(4597)
+ ..add(4598)
+ ..add(4599)
+ ..add(4600)
+ ..add(4601)
+ ..add(4602)
+ ..add(4603)
+ ..add(4604)
+ ..add(4605)
+ ..add(4606)
+ ..add(4607)
+ ..add(4608)
+ ..add(4609)
+ ..add(4610)
+ ..add(4611)
+ ..add(4612)
+ ..add(4613)
+ ..add(4614)
+ ..add(4615)
+ ..add(4616)
+ ..add(4617)
+ ..add(4618)
+ ..add(4619)
+ ..add(4620)
+ ..add(4621)
+ ..add(4622)
+ ..add(4623)
+ ..add(4624)
+ ..add(4625)
+ ..add(4626)
+ ..add(4627)
+ ..add(4628)
+ ..add(4629)
+ ..add(4630)
+ ..add(4631)
+ ..add(4632)
+ ..add(4633)
+ ..add(4634)
+ ..add(4635)
+ ..add(4636)
+ ..add(4637)
+ ..add(4638)
+ ..add(4639)
+ ..add(4640)
+ ..add(4641)
+ ..add(4642)
+ ..add(4643)
+ ..add(4644)
+ ..add(4645)
+ ..add(4646)
+ ..add(4647)
+ ..add(4648)
+ ..add(4649)
+ ..add(4650)
+ ..add(4651)
+ ..add(4652)
+ ..add(4653)
+ ..add(4654)
+ ..add(4655)
+ ..add(4656)
+ ..add(4657)
+ ..add(4658)
+ ..add(4659)
+ ..add(4660)
+ ..add(4661)
+ ..add(4662)
+ ..add(4663)
+ ..add(4664)
+ ..add(4665)
+ ..add(4666)
+ ..add(4667)
+ ..add(4668)
+ ..add(4669)
+ ..add(4670)
+ ..add(4671)
+ ..add(4672)
+ ..add(4673)
+ ..add(4674)
+ ..add(4675)
+ ..add(4676)
+ ..add(4677)
+ ..add(4678)
+ ..add(4679)
+ ..add(4680)
+ ..add(4681)
+ ..add(4682)
+ ..add(4683)
+ ..add(4684)
+ ..add(4685)
+ ..add(4686)
+ ..add(4687)
+ ..add(4688)
+ ..add(4689)
+ ..add(4690)
+ ..add(4691)
+ ..add(4692)
+ ..add(4693)
+ ..add(4694)
+ ..add(4695)
+ ..add(4696)
+ ..add(4697)
+ ..add(4698)
+ ..add(4699)
+ ..add(4700)
+ ..add(4701)
+ ..add(4702)
+ ..add(4703)
+ ..add(4704)
+ ..add(4705)
+ ..add(4706)
+ ..add(4707)
+ ..add(4708)
+ ..add(4709)
+ ..add(4710)
+ ..add(4711)
+ ..add(4712)
+ ..add(4713)
+ ..add(4714)
+ ..add(4715)
+ ..add(4716)
+ ..add(4717)
+ ..add(4718)
+ ..add(4719)
+ ..add(4720)
+ ..add(4721)
+ ..add(4722)
+ ..add(4723)
+ ..add(4724)
+ ..add(4725)
+ ..add(4726)
+ ..add(4727)
+ ..add(4728)
+ ..add(4729)
+ ..add(4730)
+ ..add(4731)
+ ..add(4732)
+ ..add(4733)
+ ..add(4734)
+ ..add(4735)
+ ..add(4736)
+ ..add(4737)
+ ..add(4738)
+ ..add(4739)
+ ..add(4740)
+ ..add(4741)
+ ..add(4742)
+ ..add(4743)
+ ..add(4744)
+ ..add(4745)
+ ..add(4746)
+ ..add(4747)
+ ..add(4748)
+ ..add(4749)
+ ..add(4750)
+ ..add(4751)
+ ..add(4752)
+ ..add(4753)
+ ..add(4754)
+ ..add(4755)
+ ..add(4756)
+ ..add(4757)
+ ..add(4758)
+ ..add(4759)
+ ..add(4760)
+ ..add(4761)
+ ..add(4762)
+ ..add(4763)
+ ..add(4764)
+ ..add(4765)
+ ..add(4766)
+ ..add(4767)
+ ..add(4768)
+ ..add(4769)
+ ..add(4770)
+ ..add(4771)
+ ..add(4772)
+ ..add(4773)
+ ..add(4774)
+ ..add(4775)
+ ..add(4776)
+ ..add(4777)
+ ..add(4778)
+ ..add(4779)
+ ..add(4780)
+ ..add(4781)
+ ..add(4782)
+ ..add(4783)
+ ..add(4784)
+ ..add(4785)
+ ..add(4786)
+ ..add(4787)
+ ..add(4788)
+ ..add(4789)
+ ..add(4790)
+ ..add(4791)
+ ..add(4792)
+ ..add(4793)
+ ..add(4794)
+ ..add(4795)
+ ..add(4796)
+ ..add(4797)
+ ..add(4798)
+ ..add(4799)
+ ..add(4800)
+ ..add(4801)
+ ..add(4802)
+ ..add(4803)
+ ..add(4804)
+ ..add(4805)
+ ..add(4806)
+ ..add(4807)
+ ..add(4808)
+ ..add(4809)
+ ..add(4810)
+ ..add(4811)
+ ..add(4812)
+ ..add(4813)
+ ..add(4814)
+ ..add(4815)
+ ..add(4816)
+ ..add(4817)
+ ..add(4818)
+ ..add(4819)
+ ..add(4820)
+ ..add(4821)
+ ..add(4822)
+ ..add(4823)
+ ..add(4824)
+ ..add(4825)
+ ..add(4826)
+ ..add(4827)
+ ..add(4828)
+ ..add(4829)
+ ..add(4830)
+ ..add(4831)
+ ..add(4832)
+ ..add(4833)
+ ..add(4834)
+ ..add(4835)
+ ..add(4836)
+ ..add(4837)
+ ..add(4838)
+ ..add(4839)
+ ..add(4840)
+ ..add(4841)
+ ..add(4842)
+ ..add(4843)
+ ..add(4844)
+ ..add(4845)
+ ..add(4846)
+ ..add(4847)
+ ..add(4848)
+ ..add(4849)
+ ..add(4850)
+ ..add(4851)
+ ..add(4852)
+ ..add(4853)
+ ..add(4854)
+ ..add(4855)
+ ..add(4856)
+ ..add(4857)
+ ..add(4858)
+ ..add(4859)
+ ..add(4860)
+ ..add(4861)
+ ..add(4862)
+ ..add(4863)
+ ..add(4864)
+ ..add(4865)
+ ..add(4866)
+ ..add(4867)
+ ..add(4868)
+ ..add(4869)
+ ..add(4870)
+ ..add(4871)
+ ..add(4872)
+ ..add(4873)
+ ..add(4874)
+ ..add(4875)
+ ..add(4876)
+ ..add(4877)
+ ..add(4878)
+ ..add(4879)
+ ..add(4880)
+ ..add(4881)
+ ..add(4882)
+ ..add(4883)
+ ..add(4884)
+ ..add(4885)
+ ..add(4886)
+ ..add(4887)
+ ..add(4888)
+ ..add(4889)
+ ..add(4890)
+ ..add(4891)
+ ..add(4892)
+ ..add(4893)
+ ..add(4894)
+ ..add(4895)
+ ..add(4896)
+ ..add(4897)
+ ..add(4898)
+ ..add(4899)
+ ..add(4900)
+ ..add(4901)
+ ..add(4902)
+ ..add(4903)
+ ..add(4904)
+ ..add(4905)
+ ..add(4906)
+ ..add(4907)
+ ..add(4908)
+ ..add(4909)
+ ..add(4910)
+ ..add(4911)
+ ..add(4912)
+ ..add(4913)
+ ..add(4914)
+ ..add(4915)
+ ..add(4916)
+ ..add(4917)
+ ..add(4918)
+ ..add(4919)
+ ..add(4920)
+ ..add(4921)
+ ..add(4922)
+ ..add(4923)
+ ..add(4924)
+ ..add(4925)
+ ..add(4926)
+ ..add(4927)
+ ..add(4928)
+ ..add(4929)
+ ..add(4930)
+ ..add(4931)
+ ..add(4932)
+ ..add(4933)
+ ..add(4934)
+ ..add(4935)
+ ..add(4936)
+ ..add(4937)
+ ..add(4938)
+ ..add(4939)
+ ..add(4940)
+ ..add(4941)
+ ..add(4942)
+ ..add(4943)
+ ..add(4944)
+ ..add(4945)
+ ..add(4946)
+ ..add(4947)
+ ..add(4948)
+ ..add(4949)
+ ..add(4950)
+ ..add(4951)
+ ..add(4952)
+ ..add(4953)
+ ..add(4954)
+ ..add(4955)
+ ..add(4956)
+ ..add(4957)
+ ..add(4958)
+ ..add(4959)
+ ..add(4960)
+ ..add(4961)
+ ..add(4962)
+ ..add(4963)
+ ..add(4964)
+ ..add(4965)
+ ..add(4966)
+ ..add(4967)
+ ..add(4968)
+ ..add(4969)
+ ..add(4970)
+ ..add(4971)
+ ..add(4972)
+ ..add(4973)
+ ..add(4974)
+ ..add(4975)
+ ..add(4976)
+ ..add(4977)
+ ..add(4978)
+ ..add(4979)
+ ..add(4980)
+ ..add(4981)
+ ..add(4982)
+ ..add(4983)
+ ..add(4984)
+ ..add(4985)
+ ..add(4986)
+ ..add(4987)
+ ..add(4988)
+ ..add(4989)
+ ..add(4990)
+ ..add(4991)
+ ..add(4992)
+ ..add(4993)
+ ..add(4994)
+ ..add(4995)
+ ..add(4996)
+ ..add(4997)
+ ..add(4998)
+ ..add(4999)
+ ..add(5000)
+ ..add(5001)
+ ..add(5002)
+ ..add(5003)
+ ..add(5004)
+ ..add(5005)
+ ..add(5006)
+ ..add(5007)
+ ..add(5008)
+ ..add(5009)
+ ..add(5010)
+ ..add(5011)
+ ..add(5012)
+ ..add(5013)
+ ..add(5014)
+ ..add(5015)
+ ..add(5016)
+ ..add(5017)
+ ..add(5018)
+ ..add(5019)
+ ..add(5020)
+ ..add(5021)
+ ..add(5022)
+ ..add(5023)
+ ..add(5024)
+ ..add(5025)
+ ..add(5026)
+ ..add(5027)
+ ..add(5028)
+ ..add(5029)
+ ..add(5030)
+ ..add(5031)
+ ..add(5032)
+ ..add(5033)
+ ..add(5034)
+ ..add(5035)
+ ..add(5036)
+ ..add(5037)
+ ..add(5038)
+ ..add(5039)
+ ..add(5040)
+ ..add(5041)
+ ..add(5042)
+ ..add(5043)
+ ..add(5044)
+ ..add(5045)
+ ..add(5046)
+ ..add(5047)
+ ..add(5048)
+ ..add(5049)
+ ..add(5050)
+ ..add(5051)
+ ..add(5052)
+ ..add(5053)
+ ..add(5054)
+ ..add(5055)
+ ..add(5056)
+ ..add(5057)
+ ..add(5058)
+ ..add(5059)
+ ..add(5060)
+ ..add(5061)
+ ..add(5062)
+ ..add(5063)
+ ..add(5064)
+ ..add(5065)
+ ..add(5066)
+ ..add(5067)
+ ..add(5068)
+ ..add(5069)
+ ..add(5070)
+ ..add(5071)
+ ..add(5072)
+ ..add(5073)
+ ..add(5074)
+ ..add(5075)
+ ..add(5076)
+ ..add(5077)
+ ..add(5078)
+ ..add(5079)
+ ..add(5080)
+ ..add(5081)
+ ..add(5082)
+ ..add(5083)
+ ..add(5084)
+ ..add(5085)
+ ..add(5086)
+ ..add(5087)
+ ..add(5088)
+ ..add(5089)
+ ..add(5090)
+ ..add(5091)
+ ..add(5092)
+ ..add(5093)
+ ..add(5094)
+ ..add(5095)
+ ..add(5096)
+ ..add(5097)
+ ..add(5098)
+ ..add(5099)
+ ..add(5100)
+ ..add(5101)
+ ..add(5102)
+ ..add(5103)
+ ..add(5104)
+ ..add(5105)
+ ..add(5106)
+ ..add(5107)
+ ..add(5108)
+ ..add(5109)
+ ..add(5110)
+ ..add(5111)
+ ..add(5112)
+ ..add(5113)
+ ..add(5114)
+ ..add(5115)
+ ..add(5116)
+ ..add(5117)
+ ..add(5118)
+ ..add(5119)
+ ..add(5120)
+ ..add(5121)
+ ..add(5122)
+ ..add(5123)
+ ..add(5124)
+ ..add(5125)
+ ..add(5126)
+ ..add(5127)
+ ..add(5128)
+ ..add(5129)
+ ..add(5130)
+ ..add(5131)
+ ..add(5132)
+ ..add(5133)
+ ..add(5134)
+ ..add(5135)
+ ..add(5136)
+ ..add(5137)
+ ..add(5138)
+ ..add(5139)
+ ..add(5140)
+ ..add(5141)
+ ..add(5142)
+ ..add(5143)
+ ..add(5144)
+ ..add(5145)
+ ..add(5146)
+ ..add(5147)
+ ..add(5148)
+ ..add(5149)
+ ..add(5150)
+ ..add(5151)
+ ..add(5152)
+ ..add(5153)
+ ..add(5154)
+ ..add(5155)
+ ..add(5156)
+ ..add(5157)
+ ..add(5158)
+ ..add(5159)
+ ..add(5160)
+ ..add(5161)
+ ..add(5162)
+ ..add(5163)
+ ..add(5164)
+ ..add(5165)
+ ..add(5166)
+ ..add(5167)
+ ..add(5168)
+ ..add(5169)
+ ..add(5170)
+ ..add(5171)
+ ..add(5172)
+ ..add(5173)
+ ..add(5174)
+ ..add(5175)
+ ..add(5176)
+ ..add(5177)
+ ..add(5178)
+ ..add(5179)
+ ..add(5180)
+ ..add(5181)
+ ..add(5182)
+ ..add(5183)
+ ..add(5184)
+ ..add(5185)
+ ..add(5186)
+ ..add(5187)
+ ..add(5188)
+ ..add(5189)
+ ..add(5190)
+ ..add(5191)
+ ..add(5192)
+ ..add(5193)
+ ..add(5194)
+ ..add(5195)
+ ..add(5196)
+ ..add(5197)
+ ..add(5198)
+ ..add(5199)
+ ..add(5200)
+ ..add(5201)
+ ..add(5202)
+ ..add(5203)
+ ..add(5204)
+ ..add(5205)
+ ..add(5206)
+ ..add(5207)
+ ..add(5208)
+ ..add(5209)
+ ..add(5210)
+ ..add(5211)
+ ..add(5212)
+ ..add(5213)
+ ..add(5214)
+ ..add(5215)
+ ..add(5216)
+ ..add(5217)
+ ..add(5218)
+ ..add(5219)
+ ..add(5220)
+ ..add(5221)
+ ..add(5222)
+ ..add(5223)
+ ..add(5224)
+ ..add(5225)
+ ..add(5226)
+ ..add(5227)
+ ..add(5228)
+ ..add(5229)
+ ..add(5230)
+ ..add(5231)
+ ..add(5232)
+ ..add(5233)
+ ..add(5234)
+ ..add(5235)
+ ..add(5236)
+ ..add(5237)
+ ..add(5238)
+ ..add(5239)
+ ..add(5240)
+ ..add(5241)
+ ..add(5242)
+ ..add(5243)
+ ..add(5244)
+ ..add(5245)
+ ..add(5246)
+ ..add(5247)
+ ..add(5248)
+ ..add(5249)
+ ..add(5250)
+ ..add(5251)
+ ..add(5252)
+ ..add(5253)
+ ..add(5254)
+ ..add(5255)
+ ..add(5256)
+ ..add(5257)
+ ..add(5258)
+ ..add(5259)
+ ..add(5260)
+ ..add(5261)
+ ..add(5262)
+ ..add(5263)
+ ..add(5264)
+ ..add(5265)
+ ..add(5266)
+ ..add(5267)
+ ..add(5268)
+ ..add(5269)
+ ..add(5270)
+ ..add(5271)
+ ..add(5272)
+ ..add(5273)
+ ..add(5274)
+ ..add(5275)
+ ..add(5276)
+ ..add(5277)
+ ..add(5278)
+ ..add(5279)
+ ..add(5280)
+ ..add(5281)
+ ..add(5282)
+ ..add(5283)
+ ..add(5284)
+ ..add(5285)
+ ..add(5286)
+ ..add(5287)
+ ..add(5288)
+ ..add(5289)
+ ..add(5290)
+ ..add(5291)
+ ..add(5292)
+ ..add(5293)
+ ..add(5294)
+ ..add(5295)
+ ..add(5296)
+ ..add(5297)
+ ..add(5298)
+ ..add(5299)
+ ..add(5300)
+ ..add(5301)
+ ..add(5302)
+ ..add(5303)
+ ..add(5304)
+ ..add(5305)
+ ..add(5306)
+ ..add(5307)
+ ..add(5308)
+ ..add(5309)
+ ..add(5310)
+ ..add(5311)
+ ..add(5312)
+ ..add(5313)
+ ..add(5314)
+ ..add(5315)
+ ..add(5316)
+ ..add(5317)
+ ..add(5318)
+ ..add(5319)
+ ..add(5320)
+ ..add(5321)
+ ..add(5322)
+ ..add(5323)
+ ..add(5324)
+ ..add(5325)
+ ..add(5326)
+ ..add(5327)
+ ..add(5328)
+ ..add(5329)
+ ..add(5330)
+ ..add(5331)
+ ..add(5332)
+ ..add(5333)
+ ..add(5334)
+ ..add(5335)
+ ..add(5336)
+ ..add(5337)
+ ..add(5338)
+ ..add(5339)
+ ..add(5340)
+ ..add(5341)
+ ..add(5342)
+ ..add(5343)
+ ..add(5344)
+ ..add(5345)
+ ..add(5346)
+ ..add(5347)
+ ..add(5348)
+ ..add(5349)
+ ..add(5350)
+ ..add(5351)
+ ..add(5352)
+ ..add(5353)
+ ..add(5354)
+ ..add(5355)
+ ..add(5356)
+ ..add(5357)
+ ..add(5358)
+ ..add(5359)
+ ..add(5360)
+ ..add(5361)
+ ..add(5362)
+ ..add(5363)
+ ..add(5364)
+ ..add(5365)
+ ..add(5366)
+ ..add(5367)
+ ..add(5368)
+ ..add(5369)
+ ..add(5370)
+ ..add(5371)
+ ..add(5372)
+ ..add(5373)
+ ..add(5374)
+ ..add(5375)
+ ..add(5376)
+ ..add(5377)
+ ..add(5378)
+ ..add(5379)
+ ..add(5380)
+ ..add(5381)
+ ..add(5382)
+ ..add(5383)
+ ..add(5384)
+ ..add(5385)
+ ..add(5386)
+ ..add(5387)
+ ..add(5388)
+ ..add(5389)
+ ..add(5390)
+ ..add(5391)
+ ..add(5392)
+ ..add(5393)
+ ..add(5394)
+ ..add(5395)
+ ..add(5396)
+ ..add(5397)
+ ..add(5398)
+ ..add(5399)
+ ..add(5400)
+ ..add(5401)
+ ..add(5402)
+ ..add(5403)
+ ..add(5404)
+ ..add(5405)
+ ..add(5406)
+ ..add(5407)
+ ..add(5408)
+ ..add(5409)
+ ..add(5410)
+ ..add(5411)
+ ..add(5412)
+ ..add(5413)
+ ..add(5414)
+ ..add(5415)
+ ..add(5416)
+ ..add(5417)
+ ..add(5418)
+ ..add(5419)
+ ..add(5420)
+ ..add(5421)
+ ..add(5422)
+ ..add(5423)
+ ..add(5424)
+ ..add(5425)
+ ..add(5426)
+ ..add(5427)
+ ..add(5428)
+ ..add(5429)
+ ..add(5430)
+ ..add(5431)
+ ..add(5432)
+ ..add(5433)
+ ..add(5434)
+ ..add(5435)
+ ..add(5436)
+ ..add(5437)
+ ..add(5438)
+ ..add(5439)
+ ..add(5440)
+ ..add(5441)
+ ..add(5442)
+ ..add(5443)
+ ..add(5444)
+ ..add(5445)
+ ..add(5446)
+ ..add(5447)
+ ..add(5448)
+ ..add(5449)
+ ..add(5450)
+ ..add(5451)
+ ..add(5452)
+ ..add(5453)
+ ..add(5454)
+ ..add(5455)
+ ..add(5456)
+ ..add(5457)
+ ..add(5458)
+ ..add(5459)
+ ..add(5460)
+ ..add(5461)
+ ..add(5462)
+ ..add(5463)
+ ..add(5464)
+ ..add(5465)
+ ..add(5466)
+ ..add(5467)
+ ..add(5468)
+ ..add(5469)
+ ..add(5470)
+ ..add(5471)
+ ..add(5472)
+ ..add(5473)
+ ..add(5474)
+ ..add(5475)
+ ..add(5476)
+ ..add(5477)
+ ..add(5478)
+ ..add(5479)
+ ..add(5480)
+ ..add(5481)
+ ..add(5482)
+ ..add(5483)
+ ..add(5484)
+ ..add(5485)
+ ..add(5486)
+ ..add(5487)
+ ..add(5488)
+ ..add(5489)
+ ..add(5490)
+ ..add(5491)
+ ..add(5492)
+ ..add(5493)
+ ..add(5494)
+ ..add(5495)
+ ..add(5496)
+ ..add(5497)
+ ..add(5498)
+ ..add(5499)
+ ..add(5500)
+ ..add(5501)
+ ..add(5502)
+ ..add(5503)
+ ..add(5504)
+ ..add(5505)
+ ..add(5506)
+ ..add(5507)
+ ..add(5508)
+ ..add(5509)
+ ..add(5510)
+ ..add(5511)
+ ..add(5512)
+ ..add(5513)
+ ..add(5514)
+ ..add(5515)
+ ..add(5516)
+ ..add(5517)
+ ..add(5518)
+ ..add(5519)
+ ..add(5520)
+ ..add(5521)
+ ..add(5522)
+ ..add(5523)
+ ..add(5524)
+ ..add(5525)
+ ..add(5526)
+ ..add(5527)
+ ..add(5528)
+ ..add(5529)
+ ..add(5530)
+ ..add(5531)
+ ..add(5532)
+ ..add(5533)
+ ..add(5534)
+ ..add(5535)
+ ..add(5536)
+ ..add(5537)
+ ..add(5538)
+ ..add(5539)
+ ..add(5540)
+ ..add(5541)
+ ..add(5542)
+ ..add(5543)
+ ..add(5544)
+ ..add(5545)
+ ..add(5546)
+ ..add(5547)
+ ..add(5548)
+ ..add(5549)
+ ..add(5550)
+ ..add(5551)
+ ..add(5552)
+ ..add(5553)
+ ..add(5554)
+ ..add(5555)
+ ..add(5556)
+ ..add(5557)
+ ..add(5558)
+ ..add(5559)
+ ..add(5560)
+ ..add(5561)
+ ..add(5562)
+ ..add(5563)
+ ..add(5564)
+ ..add(5565)
+ ..add(5566)
+ ..add(5567)
+ ..add(5568)
+ ..add(5569)
+ ..add(5570)
+ ..add(5571)
+ ..add(5572)
+ ..add(5573)
+ ..add(5574)
+ ..add(5575)
+ ..add(5576)
+ ..add(5577)
+ ..add(5578)
+ ..add(5579)
+ ..add(5580)
+ ..add(5581)
+ ..add(5582)
+ ..add(5583)
+ ..add(5584)
+ ..add(5585)
+ ..add(5586)
+ ..add(5587)
+ ..add(5588)
+ ..add(5589)
+ ..add(5590)
+ ..add(5591)
+ ..add(5592)
+ ..add(5593)
+ ..add(5594)
+ ..add(5595)
+ ..add(5596)
+ ..add(5597)
+ ..add(5598)
+ ..add(5599)
+ ..add(5600)
+ ..add(5601)
+ ..add(5602)
+ ..add(5603)
+ ..add(5604)
+ ..add(5605)
+ ..add(5606)
+ ..add(5607)
+ ..add(5608)
+ ..add(5609)
+ ..add(5610)
+ ..add(5611)
+ ..add(5612)
+ ..add(5613)
+ ..add(5614)
+ ..add(5615)
+ ..add(5616)
+ ..add(5617)
+ ..add(5618)
+ ..add(5619)
+ ..add(5620)
+ ..add(5621)
+ ..add(5622)
+ ..add(5623)
+ ..add(5624)
+ ..add(5625)
+ ..add(5626)
+ ..add(5627)
+ ..add(5628)
+ ..add(5629)
+ ..add(5630)
+ ..add(5631)
+ ..add(5632)
+ ..add(5633)
+ ..add(5634)
+ ..add(5635)
+ ..add(5636)
+ ..add(5637)
+ ..add(5638)
+ ..add(5639)
+ ..add(5640)
+ ..add(5641)
+ ..add(5642)
+ ..add(5643)
+ ..add(5644)
+ ..add(5645)
+ ..add(5646)
+ ..add(5647)
+ ..add(5648)
+ ..add(5649)
+ ..add(5650)
+ ..add(5651)
+ ..add(5652)
+ ..add(5653)
+ ..add(5654)
+ ..add(5655)
+ ..add(5656)
+ ..add(5657)
+ ..add(5658)
+ ..add(5659)
+ ..add(5660)
+ ..add(5661)
+ ..add(5662)
+ ..add(5663)
+ ..add(5664)
+ ..add(5665)
+ ..add(5666)
+ ..add(5667)
+ ..add(5668)
+ ..add(5669)
+ ..add(5670)
+ ..add(5671)
+ ..add(5672)
+ ..add(5673)
+ ..add(5674)
+ ..add(5675)
+ ..add(5676)
+ ..add(5677)
+ ..add(5678)
+ ..add(5679)
+ ..add(5680)
+ ..add(5681)
+ ..add(5682)
+ ..add(5683)
+ ..add(5684)
+ ..add(5685)
+ ..add(5686)
+ ..add(5687)
+ ..add(5688)
+ ..add(5689)
+ ..add(5690)
+ ..add(5691)
+ ..add(5692)
+ ..add(5693)
+ ..add(5694)
+ ..add(5695)
+ ..add(5696)
+ ..add(5697)
+ ..add(5698)
+ ..add(5699)
+ ..add(5700)
+ ..add(5701)
+ ..add(5702)
+ ..add(5703)
+ ..add(5704)
+ ..add(5705)
+ ..add(5706)
+ ..add(5707)
+ ..add(5708)
+ ..add(5709)
+ ..add(5710)
+ ..add(5711)
+ ..add(5712)
+ ..add(5713)
+ ..add(5714)
+ ..add(5715)
+ ..add(5716)
+ ..add(5717)
+ ..add(5718)
+ ..add(5719)
+ ..add(5720)
+ ..add(5721)
+ ..add(5722)
+ ..add(5723)
+ ..add(5724)
+ ..add(5725)
+ ..add(5726)
+ ..add(5727)
+ ..add(5728)
+ ..add(5729)
+ ..add(5730)
+ ..add(5731)
+ ..add(5732)
+ ..add(5733)
+ ..add(5734)
+ ..add(5735)
+ ..add(5736)
+ ..add(5737)
+ ..add(5738)
+ ..add(5739)
+ ..add(5740)
+ ..add(5741)
+ ..add(5742)
+ ..add(5743)
+ ..add(5744)
+ ..add(5745)
+ ..add(5746)
+ ..add(5747)
+ ..add(5748)
+ ..add(5749)
+ ..add(5750)
+ ..add(5751)
+ ..add(5752)
+ ..add(5753)
+ ..add(5754)
+ ..add(5755)
+ ..add(5756)
+ ..add(5757)
+ ..add(5758)
+ ..add(5759)
+ ..add(5760)
+ ..add(5761)
+ ..add(5762)
+ ..add(5763)
+ ..add(5764)
+ ..add(5765)
+ ..add(5766)
+ ..add(5767)
+ ..add(5768)
+ ..add(5769)
+ ..add(5770)
+ ..add(5771)
+ ..add(5772)
+ ..add(5773)
+ ..add(5774)
+ ..add(5775)
+ ..add(5776)
+ ..add(5777)
+ ..add(5778)
+ ..add(5779)
+ ..add(5780)
+ ..add(5781)
+ ..add(5782)
+ ..add(5783)
+ ..add(5784)
+ ..add(5785)
+ ..add(5786)
+ ..add(5787)
+ ..add(5788)
+ ..add(5789)
+ ..add(5790)
+ ..add(5791)
+ ..add(5792)
+ ..add(5793)
+ ..add(5794)
+ ..add(5795)
+ ..add(5796)
+ ..add(5797)
+ ..add(5798)
+ ..add(5799)
+ ..add(5800)
+ ..add(5801)
+ ..add(5802)
+ ..add(5803)
+ ..add(5804)
+ ..add(5805)
+ ..add(5806)
+ ..add(5807)
+ ..add(5808)
+ ..add(5809)
+ ..add(5810)
+ ..add(5811)
+ ..add(5812)
+ ..add(5813)
+ ..add(5814)
+ ..add(5815)
+ ..add(5816)
+ ..add(5817)
+ ..add(5818)
+ ..add(5819)
+ ..add(5820)
+ ..add(5821)
+ ..add(5822)
+ ..add(5823)
+ ..add(5824)
+ ..add(5825)
+ ..add(5826)
+ ..add(5827)
+ ..add(5828)
+ ..add(5829)
+ ..add(5830)
+ ..add(5831)
+ ..add(5832)
+ ..add(5833)
+ ..add(5834)
+ ..add(5835)
+ ..add(5836)
+ ..add(5837)
+ ..add(5838)
+ ..add(5839)
+ ..add(5840)
+ ..add(5841)
+ ..add(5842)
+ ..add(5843)
+ ..add(5844)
+ ..add(5845)
+ ..add(5846)
+ ..add(5847)
+ ..add(5848)
+ ..add(5849)
+ ..add(5850)
+ ..add(5851)
+ ..add(5852)
+ ..add(5853)
+ ..add(5854)
+ ..add(5855)
+ ..add(5856)
+ ..add(5857)
+ ..add(5858)
+ ..add(5859)
+ ..add(5860)
+ ..add(5861)
+ ..add(5862)
+ ..add(5863)
+ ..add(5864)
+ ..add(5865)
+ ..add(5866)
+ ..add(5867)
+ ..add(5868)
+ ..add(5869)
+ ..add(5870)
+ ..add(5871)
+ ..add(5872)
+ ..add(5873)
+ ..add(5874)
+ ..add(5875)
+ ..add(5876)
+ ..add(5877)
+ ..add(5878)
+ ..add(5879)
+ ..add(5880)
+ ..add(5881)
+ ..add(5882)
+ ..add(5883)
+ ..add(5884)
+ ..add(5885)
+ ..add(5886)
+ ..add(5887)
+ ..add(5888)
+ ..add(5889)
+ ..add(5890)
+ ..add(5891)
+ ..add(5892)
+ ..add(5893)
+ ..add(5894)
+ ..add(5895)
+ ..add(5896)
+ ..add(5897)
+ ..add(5898)
+ ..add(5899)
+ ..add(5900)
+ ..add(5901)
+ ..add(5902)
+ ..add(5903)
+ ..add(5904)
+ ..add(5905)
+ ..add(5906)
+ ..add(5907)
+ ..add(5908)
+ ..add(5909)
+ ..add(5910)
+ ..add(5911)
+ ..add(5912)
+ ..add(5913)
+ ..add(5914)
+ ..add(5915)
+ ..add(5916)
+ ..add(5917)
+ ..add(5918)
+ ..add(5919)
+ ..add(5920)
+ ..add(5921)
+ ..add(5922)
+ ..add(5923)
+ ..add(5924)
+ ..add(5925)
+ ..add(5926)
+ ..add(5927)
+ ..add(5928)
+ ..add(5929)
+ ..add(5930)
+ ..add(5931)
+ ..add(5932)
+ ..add(5933)
+ ..add(5934)
+ ..add(5935)
+ ..add(5936)
+ ..add(5937)
+ ..add(5938)
+ ..add(5939)
+ ..add(5940)
+ ..add(5941)
+ ..add(5942)
+ ..add(5943)
+ ..add(5944)
+ ..add(5945)
+ ..add(5946)
+ ..add(5947)
+ ..add(5948)
+ ..add(5949)
+ ..add(5950)
+ ..add(5951)
+ ..add(5952)
+ ..add(5953)
+ ..add(5954)
+ ..add(5955)
+ ..add(5956)
+ ..add(5957)
+ ..add(5958)
+ ..add(5959)
+ ..add(5960)
+ ..add(5961)
+ ..add(5962)
+ ..add(5963)
+ ..add(5964)
+ ..add(5965)
+ ..add(5966)
+ ..add(5967)
+ ..add(5968)
+ ..add(5969)
+ ..add(5970)
+ ..add(5971)
+ ..add(5972)
+ ..add(5973)
+ ..add(5974)
+ ..add(5975)
+ ..add(5976)
+ ..add(5977)
+ ..add(5978)
+ ..add(5979)
+ ..add(5980)
+ ..add(5981)
+ ..add(5982)
+ ..add(5983)
+ ..add(5984)
+ ..add(5985)
+ ..add(5986)
+ ..add(5987)
+ ..add(5988)
+ ..add(5989)
+ ..add(5990)
+ ..add(5991)
+ ..add(5992)
+ ..add(5993)
+ ..add(5994)
+ ..add(5995)
+ ..add(5996)
+ ..add(5997)
+ ..add(5998)
+ ..add(5999)
+ ..add(6000)
+ ..add(6001)
+ ..add(6002)
+ ..add(6003)
+ ..add(6004)
+ ..add(6005)
+ ..add(6006)
+ ..add(6007)
+ ..add(6008)
+ ..add(6009)
+ ..add(6010)
+ ..add(6011)
+ ..add(6012)
+ ..add(6013)
+ ..add(6014)
+ ..add(6015)
+ ..add(6016)
+ ..add(6017)
+ ..add(6018)
+ ..add(6019)
+ ..add(6020)
+ ..add(6021)
+ ..add(6022)
+ ..add(6023)
+ ..add(6024)
+ ..add(6025)
+ ..add(6026)
+ ..add(6027)
+ ..add(6028)
+ ..add(6029)
+ ..add(6030)
+ ..add(6031)
+ ..add(6032)
+ ..add(6033)
+ ..add(6034)
+ ..add(6035)
+ ..add(6036)
+ ..add(6037)
+ ..add(6038)
+ ..add(6039)
+ ..add(6040)
+ ..add(6041)
+ ..add(6042)
+ ..add(6043)
+ ..add(6044)
+ ..add(6045)
+ ..add(6046)
+ ..add(6047)
+ ..add(6048)
+ ..add(6049)
+ ..add(6050)
+ ..add(6051)
+ ..add(6052)
+ ..add(6053)
+ ..add(6054)
+ ..add(6055)
+ ..add(6056)
+ ..add(6057)
+ ..add(6058)
+ ..add(6059)
+ ..add(6060)
+ ..add(6061)
+ ..add(6062)
+ ..add(6063)
+ ..add(6064)
+ ..add(6065)
+ ..add(6066)
+ ..add(6067)
+ ..add(6068)
+ ..add(6069)
+ ..add(6070)
+ ..add(6071)
+ ..add(6072)
+ ..add(6073)
+ ..add(6074)
+ ..add(6075)
+ ..add(6076)
+ ..add(6077)
+ ..add(6078)
+ ..add(6079)
+ ..add(6080)
+ ..add(6081)
+ ..add(6082)
+ ..add(6083)
+ ..add(6084)
+ ..add(6085)
+ ..add(6086)
+ ..add(6087)
+ ..add(6088)
+ ..add(6089)
+ ..add(6090)
+ ..add(6091)
+ ..add(6092)
+ ..add(6093)
+ ..add(6094)
+ ..add(6095)
+ ..add(6096)
+ ..add(6097)
+ ..add(6098)
+ ..add(6099)
+ ..add(6100)
+ ..add(6101)
+ ..add(6102)
+ ..add(6103)
+ ..add(6104)
+ ..add(6105)
+ ..add(6106)
+ ..add(6107)
+ ..add(6108)
+ ..add(6109)
+ ..add(6110)
+ ..add(6111)
+ ..add(6112)
+ ..add(6113)
+ ..add(6114)
+ ..add(6115)
+ ..add(6116)
+ ..add(6117)
+ ..add(6118)
+ ..add(6119)
+ ..add(6120)
+ ..add(6121)
+ ..add(6122)
+ ..add(6123)
+ ..add(6124)
+ ..add(6125)
+ ..add(6126)
+ ..add(6127)
+ ..add(6128)
+ ..add(6129)
+ ..add(6130)
+ ..add(6131)
+ ..add(6132)
+ ..add(6133)
+ ..add(6134)
+ ..add(6135)
+ ..add(6136)
+ ..add(6137)
+ ..add(6138)
+ ..add(6139)
+ ..add(6140)
+ ..add(6141)
+ ..add(6142)
+ ..add(6143)
+ ..add(6144)
+ ..add(6145)
+ ..add(6146)
+ ..add(6147)
+ ..add(6148)
+ ..add(6149)
+ ..add(6150)
+ ..add(6151)
+ ..add(6152)
+ ..add(6153)
+ ..add(6154)
+ ..add(6155)
+ ..add(6156)
+ ..add(6157)
+ ..add(6158)
+ ..add(6159)
+ ..add(6160)
+ ..add(6161)
+ ..add(6162)
+ ..add(6163)
+ ..add(6164)
+ ..add(6165)
+ ..add(6166)
+ ..add(6167)
+ ..add(6168)
+ ..add(6169)
+ ..add(6170)
+ ..add(6171)
+ ..add(6172)
+ ..add(6173)
+ ..add(6174)
+ ..add(6175)
+ ..add(6176)
+ ..add(6177)
+ ..add(6178)
+ ..add(6179)
+ ..add(6180)
+ ..add(6181)
+ ..add(6182)
+ ..add(6183)
+ ..add(6184)
+ ..add(6185)
+ ..add(6186)
+ ..add(6187)
+ ..add(6188)
+ ..add(6189)
+ ..add(6190)
+ ..add(6191)
+ ..add(6192)
+ ..add(6193)
+ ..add(6194)
+ ..add(6195)
+ ..add(6196)
+ ..add(6197)
+ ..add(6198)
+ ..add(6199)
+ ..add(6200)
+ ..add(6201)
+ ..add(6202)
+ ..add(6203)
+ ..add(6204)
+ ..add(6205)
+ ..add(6206)
+ ..add(6207)
+ ..add(6208)
+ ..add(6209)
+ ..add(6210)
+ ..add(6211)
+ ..add(6212)
+ ..add(6213)
+ ..add(6214)
+ ..add(6215)
+ ..add(6216)
+ ..add(6217)
+ ..add(6218)
+ ..add(6219)
+ ..add(6220)
+ ..add(6221)
+ ..add(6222)
+ ..add(6223)
+ ..add(6224)
+ ..add(6225)
+ ..add(6226)
+ ..add(6227)
+ ..add(6228)
+ ..add(6229)
+ ..add(6230)
+ ..add(6231)
+ ..add(6232)
+ ..add(6233)
+ ..add(6234)
+ ..add(6235)
+ ..add(6236)
+ ..add(6237)
+ ..add(6238)
+ ..add(6239)
+ ..add(6240)
+ ..add(6241)
+ ..add(6242)
+ ..add(6243)
+ ..add(6244)
+ ..add(6245)
+ ..add(6246)
+ ..add(6247)
+ ..add(6248)
+ ..add(6249)
+ ..add(6250)
+ ..add(6251)
+ ..add(6252)
+ ..add(6253)
+ ..add(6254)
+ ..add(6255)
+ ..add(6256)
+ ..add(6257)
+ ..add(6258)
+ ..add(6259)
+ ..add(6260)
+ ..add(6261)
+ ..add(6262)
+ ..add(6263)
+ ..add(6264)
+ ..add(6265)
+ ..add(6266)
+ ..add(6267)
+ ..add(6268)
+ ..add(6269)
+ ..add(6270)
+ ..add(6271)
+ ..add(6272)
+ ..add(6273)
+ ..add(6274)
+ ..add(6275)
+ ..add(6276)
+ ..add(6277)
+ ..add(6278)
+ ..add(6279)
+ ..add(6280)
+ ..add(6281)
+ ..add(6282)
+ ..add(6283)
+ ..add(6284)
+ ..add(6285)
+ ..add(6286)
+ ..add(6287)
+ ..add(6288)
+ ..add(6289)
+ ..add(6290)
+ ..add(6291)
+ ..add(6292)
+ ..add(6293)
+ ..add(6294)
+ ..add(6295)
+ ..add(6296)
+ ..add(6297)
+ ..add(6298)
+ ..add(6299)
+ ..add(6300)
+ ..add(6301)
+ ..add(6302)
+ ..add(6303)
+ ..add(6304)
+ ..add(6305)
+ ..add(6306)
+ ..add(6307)
+ ..add(6308)
+ ..add(6309)
+ ..add(6310)
+ ..add(6311)
+ ..add(6312)
+ ..add(6313)
+ ..add(6314)
+ ..add(6315)
+ ..add(6316)
+ ..add(6317)
+ ..add(6318)
+ ..add(6319)
+ ..add(6320)
+ ..add(6321)
+ ..add(6322)
+ ..add(6323)
+ ..add(6324)
+ ..add(6325)
+ ..add(6326)
+ ..add(6327)
+ ..add(6328)
+ ..add(6329)
+ ..add(6330)
+ ..add(6331)
+ ..add(6332)
+ ..add(6333)
+ ..add(6334)
+ ..add(6335)
+ ..add(6336)
+ ..add(6337)
+ ..add(6338)
+ ..add(6339)
+ ..add(6340)
+ ..add(6341)
+ ..add(6342)
+ ..add(6343)
+ ..add(6344)
+ ..add(6345)
+ ..add(6346)
+ ..add(6347)
+ ..add(6348)
+ ..add(6349)
+ ..add(6350)
+ ..add(6351)
+ ..add(6352)
+ ..add(6353)
+ ..add(6354)
+ ..add(6355)
+ ..add(6356)
+ ..add(6357)
+ ..add(6358)
+ ..add(6359)
+ ..add(6360)
+ ..add(6361)
+ ..add(6362)
+ ..add(6363)
+ ..add(6364)
+ ..add(6365)
+ ..add(6366)
+ ..add(6367)
+ ..add(6368)
+ ..add(6369)
+ ..add(6370)
+ ..add(6371)
+ ..add(6372)
+ ..add(6373)
+ ..add(6374)
+ ..add(6375)
+ ..add(6376)
+ ..add(6377)
+ ..add(6378)
+ ..add(6379)
+ ..add(6380)
+ ..add(6381)
+ ..add(6382)
+ ..add(6383)
+ ..add(6384)
+ ..add(6385)
+ ..add(6386)
+ ..add(6387)
+ ..add(6388)
+ ..add(6389)
+ ..add(6390)
+ ..add(6391)
+ ..add(6392)
+ ..add(6393)
+ ..add(6394)
+ ..add(6395)
+ ..add(6396)
+ ..add(6397)
+ ..add(6398)
+ ..add(6399)
+ ..add(6400)
+ ..add(6401)
+ ..add(6402)
+ ..add(6403)
+ ..add(6404)
+ ..add(6405)
+ ..add(6406)
+ ..add(6407)
+ ..add(6408)
+ ..add(6409)
+ ..add(6410)
+ ..add(6411)
+ ..add(6412)
+ ..add(6413)
+ ..add(6414)
+ ..add(6415)
+ ..add(6416)
+ ..add(6417)
+ ..add(6418)
+ ..add(6419)
+ ..add(6420)
+ ..add(6421)
+ ..add(6422)
+ ..add(6423)
+ ..add(6424)
+ ..add(6425)
+ ..add(6426)
+ ..add(6427)
+ ..add(6428)
+ ..add(6429)
+ ..add(6430)
+ ..add(6431)
+ ..add(6432)
+ ..add(6433)
+ ..add(6434)
+ ..add(6435)
+ ..add(6436)
+ ..add(6437)
+ ..add(6438)
+ ..add(6439)
+ ..add(6440)
+ ..add(6441)
+ ..add(6442)
+ ..add(6443)
+ ..add(6444)
+ ..add(6445)
+ ..add(6446)
+ ..add(6447)
+ ..add(6448)
+ ..add(6449)
+ ..add(6450)
+ ..add(6451)
+ ..add(6452)
+ ..add(6453)
+ ..add(6454)
+ ..add(6455)
+ ..add(6456)
+ ..add(6457)
+ ..add(6458)
+ ..add(6459)
+ ..add(6460)
+ ..add(6461)
+ ..add(6462)
+ ..add(6463)
+ ..add(6464)
+ ..add(6465)
+ ..add(6466)
+ ..add(6467)
+ ..add(6468)
+ ..add(6469)
+ ..add(6470)
+ ..add(6471)
+ ..add(6472)
+ ..add(6473)
+ ..add(6474)
+ ..add(6475)
+ ..add(6476)
+ ..add(6477)
+ ..add(6478)
+ ..add(6479)
+ ..add(6480)
+ ..add(6481)
+ ..add(6482)
+ ..add(6483)
+ ..add(6484)
+ ..add(6485)
+ ..add(6486)
+ ..add(6487)
+ ..add(6488)
+ ..add(6489)
+ ..add(6490)
+ ..add(6491)
+ ..add(6492)
+ ..add(6493)
+ ..add(6494)
+ ..add(6495)
+ ..add(6496)
+ ..add(6497)
+ ..add(6498)
+ ..add(6499)
+ ..add(6500)
+ ..add(6501)
+ ..add(6502)
+ ..add(6503)
+ ..add(6504)
+ ..add(6505)
+ ..add(6506)
+ ..add(6507)
+ ..add(6508)
+ ..add(6509)
+ ..add(6510)
+ ..add(6511)
+ ..add(6512)
+ ..add(6513)
+ ..add(6514)
+ ..add(6515)
+ ..add(6516)
+ ..add(6517)
+ ..add(6518)
+ ..add(6519)
+ ..add(6520)
+ ..add(6521)
+ ..add(6522)
+ ..add(6523)
+ ..add(6524)
+ ..add(6525)
+ ..add(6526)
+ ..add(6527)
+ ..add(6528)
+ ..add(6529)
+ ..add(6530)
+ ..add(6531)
+ ..add(6532)
+ ..add(6533)
+ ..add(6534)
+ ..add(6535)
+ ..add(6536)
+ ..add(6537)
+ ..add(6538)
+ ..add(6539)
+ ..add(6540)
+ ..add(6541)
+ ..add(6542)
+ ..add(6543)
+ ..add(6544)
+ ..add(6545)
+ ..add(6546)
+ ..add(6547)
+ ..add(6548)
+ ..add(6549)
+ ..add(6550)
+ ..add(6551)
+ ..add(6552)
+ ..add(6553)
+ ..add(6554)
+ ..add(6555)
+ ..add(6556)
+ ..add(6557)
+ ..add(6558)
+ ..add(6559)
+ ..add(6560)
+ ..add(6561)
+ ..add(6562)
+ ..add(6563)
+ ..add(6564)
+ ..add(6565)
+ ..add(6566)
+ ..add(6567)
+ ..add(6568)
+ ..add(6569)
+ ..add(6570)
+ ..add(6571)
+ ..add(6572)
+ ..add(6573)
+ ..add(6574)
+ ..add(6575)
+ ..add(6576)
+ ..add(6577)
+ ..add(6578)
+ ..add(6579)
+ ..add(6580)
+ ..add(6581)
+ ..add(6582)
+ ..add(6583)
+ ..add(6584)
+ ..add(6585)
+ ..add(6586)
+ ..add(6587)
+ ..add(6588)
+ ..add(6589)
+ ..add(6590)
+ ..add(6591)
+ ..add(6592)
+ ..add(6593)
+ ..add(6594)
+ ..add(6595)
+ ..add(6596)
+ ..add(6597)
+ ..add(6598)
+ ..add(6599)
+ ..add(6600)
+ ..add(6601)
+ ..add(6602)
+ ..add(6603)
+ ..add(6604)
+ ..add(6605)
+ ..add(6606)
+ ..add(6607)
+ ..add(6608)
+ ..add(6609)
+ ..add(6610)
+ ..add(6611)
+ ..add(6612)
+ ..add(6613)
+ ..add(6614)
+ ..add(6615)
+ ..add(6616)
+ ..add(6617)
+ ..add(6618)
+ ..add(6619)
+ ..add(6620)
+ ..add(6621)
+ ..add(6622)
+ ..add(6623)
+ ..add(6624)
+ ..add(6625)
+ ..add(6626)
+ ..add(6627)
+ ..add(6628)
+ ..add(6629)
+ ..add(6630)
+ ..add(6631)
+ ..add(6632)
+ ..add(6633)
+ ..add(6634)
+ ..add(6635)
+ ..add(6636)
+ ..add(6637)
+ ..add(6638)
+ ..add(6639)
+ ..add(6640)
+ ..add(6641)
+ ..add(6642)
+ ..add(6643)
+ ..add(6644)
+ ..add(6645)
+ ..add(6646)
+ ..add(6647)
+ ..add(6648)
+ ..add(6649)
+ ..add(6650)
+ ..add(6651)
+ ..add(6652)
+ ..add(6653)
+ ..add(6654)
+ ..add(6655)
+ ..add(6656)
+ ..add(6657)
+ ..add(6658)
+ ..add(6659)
+ ..add(6660)
+ ..add(6661)
+ ..add(6662)
+ ..add(6663)
+ ..add(6664)
+ ..add(6665)
+ ..add(6666)
+ ..add(6667)
+ ..add(6668)
+ ..add(6669)
+ ..add(6670)
+ ..add(6671)
+ ..add(6672)
+ ..add(6673)
+ ..add(6674)
+ ..add(6675)
+ ..add(6676)
+ ..add(6677)
+ ..add(6678)
+ ..add(6679)
+ ..add(6680)
+ ..add(6681)
+ ..add(6682)
+ ..add(6683)
+ ..add(6684)
+ ..add(6685)
+ ..add(6686)
+ ..add(6687)
+ ..add(6688)
+ ..add(6689)
+ ..add(6690)
+ ..add(6691)
+ ..add(6692)
+ ..add(6693)
+ ..add(6694)
+ ..add(6695)
+ ..add(6696)
+ ..add(6697)
+ ..add(6698)
+ ..add(6699)
+ ..add(6700)
+ ..add(6701)
+ ..add(6702)
+ ..add(6703)
+ ..add(6704)
+ ..add(6705)
+ ..add(6706)
+ ..add(6707)
+ ..add(6708)
+ ..add(6709)
+ ..add(6710)
+ ..add(6711)
+ ..add(6712)
+ ..add(6713)
+ ..add(6714)
+ ..add(6715)
+ ..add(6716)
+ ..add(6717)
+ ..add(6718)
+ ..add(6719)
+ ..add(6720)
+ ..add(6721)
+ ..add(6722)
+ ..add(6723)
+ ..add(6724)
+ ..add(6725)
+ ..add(6726)
+ ..add(6727)
+ ..add(6728)
+ ..add(6729)
+ ..add(6730)
+ ..add(6731)
+ ..add(6732)
+ ..add(6733)
+ ..add(6734)
+ ..add(6735)
+ ..add(6736)
+ ..add(6737)
+ ..add(6738)
+ ..add(6739)
+ ..add(6740)
+ ..add(6741)
+ ..add(6742)
+ ..add(6743)
+ ..add(6744)
+ ..add(6745)
+ ..add(6746)
+ ..add(6747)
+ ..add(6748)
+ ..add(6749)
+ ..add(6750)
+ ..add(6751)
+ ..add(6752)
+ ..add(6753)
+ ..add(6754)
+ ..add(6755)
+ ..add(6756)
+ ..add(6757)
+ ..add(6758)
+ ..add(6759)
+ ..add(6760)
+ ..add(6761)
+ ..add(6762)
+ ..add(6763)
+ ..add(6764)
+ ..add(6765)
+ ..add(6766)
+ ..add(6767)
+ ..add(6768)
+ ..add(6769)
+ ..add(6770)
+ ..add(6771)
+ ..add(6772)
+ ..add(6773)
+ ..add(6774)
+ ..add(6775)
+ ..add(6776)
+ ..add(6777)
+ ..add(6778)
+ ..add(6779)
+ ..add(6780)
+ ..add(6781)
+ ..add(6782)
+ ..add(6783)
+ ..add(6784)
+ ..add(6785)
+ ..add(6786)
+ ..add(6787)
+ ..add(6788)
+ ..add(6789)
+ ..add(6790)
+ ..add(6791)
+ ..add(6792)
+ ..add(6793)
+ ..add(6794)
+ ..add(6795)
+ ..add(6796)
+ ..add(6797)
+ ..add(6798)
+ ..add(6799)
+ ..add(6800)
+ ..add(6801)
+ ..add(6802)
+ ..add(6803)
+ ..add(6804)
+ ..add(6805)
+ ..add(6806)
+ ..add(6807)
+ ..add(6808)
+ ..add(6809)
+ ..add(6810)
+ ..add(6811)
+ ..add(6812)
+ ..add(6813)
+ ..add(6814)
+ ..add(6815)
+ ..add(6816)
+ ..add(6817)
+ ..add(6818)
+ ..add(6819)
+ ..add(6820)
+ ..add(6821)
+ ..add(6822)
+ ..add(6823)
+ ..add(6824)
+ ..add(6825)
+ ..add(6826)
+ ..add(6827)
+ ..add(6828)
+ ..add(6829)
+ ..add(6830)
+ ..add(6831)
+ ..add(6832)
+ ..add(6833)
+ ..add(6834)
+ ..add(6835)
+ ..add(6836)
+ ..add(6837)
+ ..add(6838)
+ ..add(6839)
+ ..add(6840)
+ ..add(6841)
+ ..add(6842)
+ ..add(6843)
+ ..add(6844)
+ ..add(6845)
+ ..add(6846)
+ ..add(6847)
+ ..add(6848)
+ ..add(6849)
+ ..add(6850)
+ ..add(6851)
+ ..add(6852)
+ ..add(6853)
+ ..add(6854)
+ ..add(6855)
+ ..add(6856)
+ ..add(6857)
+ ..add(6858)
+ ..add(6859)
+ ..add(6860)
+ ..add(6861)
+ ..add(6862)
+ ..add(6863)
+ ..add(6864)
+ ..add(6865)
+ ..add(6866)
+ ..add(6867)
+ ..add(6868)
+ ..add(6869)
+ ..add(6870)
+ ..add(6871)
+ ..add(6872)
+ ..add(6873)
+ ..add(6874)
+ ..add(6875)
+ ..add(6876)
+ ..add(6877)
+ ..add(6878)
+ ..add(6879)
+ ..add(6880)
+ ..add(6881)
+ ..add(6882)
+ ..add(6883)
+ ..add(6884)
+ ..add(6885)
+ ..add(6886)
+ ..add(6887)
+ ..add(6888)
+ ..add(6889)
+ ..add(6890)
+ ..add(6891)
+ ..add(6892)
+ ..add(6893)
+ ..add(6894)
+ ..add(6895)
+ ..add(6896)
+ ..add(6897)
+ ..add(6898)
+ ..add(6899)
+ ..add(6900)
+ ..add(6901)
+ ..add(6902)
+ ..add(6903)
+ ..add(6904)
+ ..add(6905)
+ ..add(6906)
+ ..add(6907)
+ ..add(6908)
+ ..add(6909)
+ ..add(6910)
+ ..add(6911)
+ ..add(6912)
+ ..add(6913)
+ ..add(6914)
+ ..add(6915)
+ ..add(6916)
+ ..add(6917)
+ ..add(6918)
+ ..add(6919)
+ ..add(6920)
+ ..add(6921)
+ ..add(6922)
+ ..add(6923)
+ ..add(6924)
+ ..add(6925)
+ ..add(6926)
+ ..add(6927)
+ ..add(6928)
+ ..add(6929)
+ ..add(6930)
+ ..add(6931)
+ ..add(6932)
+ ..add(6933)
+ ..add(6934)
+ ..add(6935)
+ ..add(6936)
+ ..add(6937)
+ ..add(6938)
+ ..add(6939)
+ ..add(6940)
+ ..add(6941)
+ ..add(6942)
+ ..add(6943)
+ ..add(6944)
+ ..add(6945)
+ ..add(6946)
+ ..add(6947)
+ ..add(6948)
+ ..add(6949)
+ ..add(6950)
+ ..add(6951)
+ ..add(6952)
+ ..add(6953)
+ ..add(6954)
+ ..add(6955)
+ ..add(6956)
+ ..add(6957)
+ ..add(6958)
+ ..add(6959)
+ ..add(6960)
+ ..add(6961)
+ ..add(6962)
+ ..add(6963)
+ ..add(6964)
+ ..add(6965)
+ ..add(6966)
+ ..add(6967)
+ ..add(6968)
+ ..add(6969)
+ ..add(6970)
+ ..add(6971)
+ ..add(6972)
+ ..add(6973)
+ ..add(6974)
+ ..add(6975)
+ ..add(6976)
+ ..add(6977)
+ ..add(6978)
+ ..add(6979)
+ ..add(6980)
+ ..add(6981)
+ ..add(6982)
+ ..add(6983)
+ ..add(6984)
+ ..add(6985)
+ ..add(6986)
+ ..add(6987)
+ ..add(6988)
+ ..add(6989)
+ ..add(6990)
+ ..add(6991)
+ ..add(6992)
+ ..add(6993)
+ ..add(6994)
+ ..add(6995)
+ ..add(6996)
+ ..add(6997)
+ ..add(6998)
+ ..add(6999)
+ ..add(7000)
+ ..add(7001)
+ ..add(7002)
+ ..add(7003)
+ ..add(7004)
+ ..add(7005)
+ ..add(7006)
+ ..add(7007)
+ ..add(7008)
+ ..add(7009)
+ ..add(7010)
+ ..add(7011)
+ ..add(7012)
+ ..add(7013)
+ ..add(7014)
+ ..add(7015)
+ ..add(7016)
+ ..add(7017)
+ ..add(7018)
+ ..add(7019)
+ ..add(7020)
+ ..add(7021)
+ ..add(7022)
+ ..add(7023)
+ ..add(7024)
+ ..add(7025)
+ ..add(7026)
+ ..add(7027)
+ ..add(7028)
+ ..add(7029)
+ ..add(7030)
+ ..add(7031)
+ ..add(7032)
+ ..add(7033)
+ ..add(7034)
+ ..add(7035)
+ ..add(7036)
+ ..add(7037)
+ ..add(7038)
+ ..add(7039)
+ ..add(7040)
+ ..add(7041)
+ ..add(7042)
+ ..add(7043)
+ ..add(7044)
+ ..add(7045)
+ ..add(7046)
+ ..add(7047)
+ ..add(7048)
+ ..add(7049)
+ ..add(7050)
+ ..add(7051)
+ ..add(7052)
+ ..add(7053)
+ ..add(7054)
+ ..add(7055)
+ ..add(7056)
+ ..add(7057)
+ ..add(7058)
+ ..add(7059)
+ ..add(7060)
+ ..add(7061)
+ ..add(7062)
+ ..add(7063)
+ ..add(7064)
+ ..add(7065)
+ ..add(7066)
+ ..add(7067)
+ ..add(7068)
+ ..add(7069)
+ ..add(7070)
+ ..add(7071)
+ ..add(7072)
+ ..add(7073)
+ ..add(7074)
+ ..add(7075)
+ ..add(7076)
+ ..add(7077)
+ ..add(7078)
+ ..add(7079)
+ ..add(7080)
+ ..add(7081)
+ ..add(7082)
+ ..add(7083)
+ ..add(7084)
+ ..add(7085)
+ ..add(7086)
+ ..add(7087)
+ ..add(7088)
+ ..add(7089)
+ ..add(7090)
+ ..add(7091)
+ ..add(7092)
+ ..add(7093)
+ ..add(7094)
+ ..add(7095)
+ ..add(7096)
+ ..add(7097)
+ ..add(7098)
+ ..add(7099)
+ ..add(7100)
+ ..add(7101)
+ ..add(7102)
+ ..add(7103)
+ ..add(7104)
+ ..add(7105)
+ ..add(7106)
+ ..add(7107)
+ ..add(7108)
+ ..add(7109)
+ ..add(7110)
+ ..add(7111)
+ ..add(7112)
+ ..add(7113)
+ ..add(7114)
+ ..add(7115)
+ ..add(7116)
+ ..add(7117)
+ ..add(7118)
+ ..add(7119)
+ ..add(7120)
+ ..add(7121)
+ ..add(7122)
+ ..add(7123)
+ ..add(7124)
+ ..add(7125)
+ ..add(7126)
+ ..add(7127)
+ ..add(7128)
+ ..add(7129)
+ ..add(7130)
+ ..add(7131)
+ ..add(7132)
+ ..add(7133)
+ ..add(7134)
+ ..add(7135)
+ ..add(7136)
+ ..add(7137)
+ ..add(7138)
+ ..add(7139)
+ ..add(7140)
+ ..add(7141)
+ ..add(7142)
+ ..add(7143)
+ ..add(7144)
+ ..add(7145)
+ ..add(7146)
+ ..add(7147)
+ ..add(7148)
+ ..add(7149)
+ ..add(7150)
+ ..add(7151)
+ ..add(7152)
+ ..add(7153)
+ ..add(7154)
+ ..add(7155)
+ ..add(7156)
+ ..add(7157)
+ ..add(7158)
+ ..add(7159)
+ ..add(7160)
+ ..add(7161)
+ ..add(7162)
+ ..add(7163)
+ ..add(7164)
+ ..add(7165)
+ ..add(7166)
+ ..add(7167)
+ ..add(7168)
+ ..add(7169)
+ ..add(7170)
+ ..add(7171)
+ ..add(7172)
+ ..add(7173)
+ ..add(7174)
+ ..add(7175)
+ ..add(7176)
+ ..add(7177)
+ ..add(7178)
+ ..add(7179)
+ ..add(7180)
+ ..add(7181)
+ ..add(7182)
+ ..add(7183)
+ ..add(7184)
+ ..add(7185)
+ ..add(7186)
+ ..add(7187)
+ ..add(7188)
+ ..add(7189)
+ ..add(7190)
+ ..add(7191)
+ ..add(7192)
+ ..add(7193)
+ ..add(7194)
+ ..add(7195)
+ ..add(7196)
+ ..add(7197)
+ ..add(7198)
+ ..add(7199)
+ ..add(7200)
+ ..add(7201)
+ ..add(7202)
+ ..add(7203)
+ ..add(7204)
+ ..add(7205)
+ ..add(7206)
+ ..add(7207)
+ ..add(7208)
+ ..add(7209)
+ ..add(7210)
+ ..add(7211)
+ ..add(7212)
+ ..add(7213)
+ ..add(7214)
+ ..add(7215)
+ ..add(7216)
+ ..add(7217)
+ ..add(7218)
+ ..add(7219)
+ ..add(7220)
+ ..add(7221)
+ ..add(7222)
+ ..add(7223)
+ ..add(7224)
+ ..add(7225)
+ ..add(7226)
+ ..add(7227)
+ ..add(7228)
+ ..add(7229)
+ ..add(7230)
+ ..add(7231)
+ ..add(7232)
+ ..add(7233)
+ ..add(7234)
+ ..add(7235)
+ ..add(7236)
+ ..add(7237)
+ ..add(7238)
+ ..add(7239)
+ ..add(7240)
+ ..add(7241)
+ ..add(7242)
+ ..add(7243)
+ ..add(7244)
+ ..add(7245)
+ ..add(7246)
+ ..add(7247)
+ ..add(7248)
+ ..add(7249)
+ ..add(7250)
+ ..add(7251)
+ ..add(7252)
+ ..add(7253)
+ ..add(7254)
+ ..add(7255)
+ ..add(7256)
+ ..add(7257)
+ ..add(7258)
+ ..add(7259)
+ ..add(7260)
+ ..add(7261)
+ ..add(7262)
+ ..add(7263)
+ ..add(7264)
+ ..add(7265)
+ ..add(7266)
+ ..add(7267)
+ ..add(7268)
+ ..add(7269)
+ ..add(7270)
+ ..add(7271)
+ ..add(7272)
+ ..add(7273)
+ ..add(7274)
+ ..add(7275)
+ ..add(7276)
+ ..add(7277)
+ ..add(7278)
+ ..add(7279)
+ ..add(7280)
+ ..add(7281)
+ ..add(7282)
+ ..add(7283)
+ ..add(7284)
+ ..add(7285)
+ ..add(7286)
+ ..add(7287)
+ ..add(7288)
+ ..add(7289)
+ ..add(7290)
+ ..add(7291)
+ ..add(7292)
+ ..add(7293)
+ ..add(7294)
+ ..add(7295)
+ ..add(7296)
+ ..add(7297)
+ ..add(7298)
+ ..add(7299)
+ ..add(7300)
+ ..add(7301)
+ ..add(7302)
+ ..add(7303)
+ ..add(7304)
+ ..add(7305)
+ ..add(7306)
+ ..add(7307)
+ ..add(7308)
+ ..add(7309)
+ ..add(7310)
+ ..add(7311)
+ ..add(7312)
+ ..add(7313)
+ ..add(7314)
+ ..add(7315)
+ ..add(7316)
+ ..add(7317)
+ ..add(7318)
+ ..add(7319)
+ ..add(7320)
+ ..add(7321)
+ ..add(7322)
+ ..add(7323)
+ ..add(7324)
+ ..add(7325)
+ ..add(7326)
+ ..add(7327)
+ ..add(7328)
+ ..add(7329)
+ ..add(7330)
+ ..add(7331)
+ ..add(7332)
+ ..add(7333)
+ ..add(7334)
+ ..add(7335)
+ ..add(7336)
+ ..add(7337)
+ ..add(7338)
+ ..add(7339)
+ ..add(7340)
+ ..add(7341)
+ ..add(7342)
+ ..add(7343)
+ ..add(7344)
+ ..add(7345)
+ ..add(7346)
+ ..add(7347)
+ ..add(7348)
+ ..add(7349)
+ ..add(7350)
+ ..add(7351)
+ ..add(7352)
+ ..add(7353)
+ ..add(7354)
+ ..add(7355)
+ ..add(7356)
+ ..add(7357)
+ ..add(7358)
+ ..add(7359)
+ ..add(7360)
+ ..add(7361)
+ ..add(7362)
+ ..add(7363)
+ ..add(7364)
+ ..add(7365)
+ ..add(7366)
+ ..add(7367)
+ ..add(7368)
+ ..add(7369)
+ ..add(7370)
+ ..add(7371)
+ ..add(7372)
+ ..add(7373)
+ ..add(7374)
+ ..add(7375)
+ ..add(7376)
+ ..add(7377)
+ ..add(7378)
+ ..add(7379)
+ ..add(7380)
+ ..add(7381)
+ ..add(7382)
+ ..add(7383)
+ ..add(7384)
+ ..add(7385)
+ ..add(7386)
+ ..add(7387)
+ ..add(7388)
+ ..add(7389)
+ ..add(7390)
+ ..add(7391)
+ ..add(7392)
+ ..add(7393)
+ ..add(7394)
+ ..add(7395)
+ ..add(7396)
+ ..add(7397)
+ ..add(7398)
+ ..add(7399)
+ ..add(7400)
+ ..add(7401)
+ ..add(7402)
+ ..add(7403)
+ ..add(7404)
+ ..add(7405)
+ ..add(7406)
+ ..add(7407)
+ ..add(7408)
+ ..add(7409)
+ ..add(7410)
+ ..add(7411)
+ ..add(7412)
+ ..add(7413)
+ ..add(7414)
+ ..add(7415)
+ ..add(7416)
+ ..add(7417)
+ ..add(7418)
+ ..add(7419)
+ ..add(7420)
+ ..add(7421)
+ ..add(7422)
+ ..add(7423)
+ ..add(7424)
+ ..add(7425)
+ ..add(7426)
+ ..add(7427)
+ ..add(7428)
+ ..add(7429)
+ ..add(7430)
+ ..add(7431)
+ ..add(7432)
+ ..add(7433)
+ ..add(7434)
+ ..add(7435)
+ ..add(7436)
+ ..add(7437)
+ ..add(7438)
+ ..add(7439)
+ ..add(7440)
+ ..add(7441)
+ ..add(7442)
+ ..add(7443)
+ ..add(7444)
+ ..add(7445)
+ ..add(7446)
+ ..add(7447)
+ ..add(7448)
+ ..add(7449)
+ ..add(7450)
+ ..add(7451)
+ ..add(7452)
+ ..add(7453)
+ ..add(7454)
+ ..add(7455)
+ ..add(7456)
+ ..add(7457)
+ ..add(7458)
+ ..add(7459)
+ ..add(7460)
+ ..add(7461)
+ ..add(7462)
+ ..add(7463)
+ ..add(7464)
+ ..add(7465)
+ ..add(7466)
+ ..add(7467)
+ ..add(7468)
+ ..add(7469)
+ ..add(7470)
+ ..add(7471)
+ ..add(7472)
+ ..add(7473)
+ ..add(7474)
+ ..add(7475)
+ ..add(7476)
+ ..add(7477)
+ ..add(7478)
+ ..add(7479)
+ ..add(7480)
+ ..add(7481)
+ ..add(7482)
+ ..add(7483)
+ ..add(7484)
+ ..add(7485)
+ ..add(7486)
+ ..add(7487)
+ ..add(7488)
+ ..add(7489)
+ ..add(7490)
+ ..add(7491)
+ ..add(7492)
+ ..add(7493)
+ ..add(7494)
+ ..add(7495)
+ ..add(7496)
+ ..add(7497)
+ ..add(7498)
+ ..add(7499)
+ ..add(7500)
+ ..add(7501)
+ ..add(7502)
+ ..add(7503)
+ ..add(7504)
+ ..add(7505)
+ ..add(7506)
+ ..add(7507)
+ ..add(7508)
+ ..add(7509)
+ ..add(7510)
+ ..add(7511)
+ ..add(7512)
+ ..add(7513)
+ ..add(7514)
+ ..add(7515)
+ ..add(7516)
+ ..add(7517)
+ ..add(7518)
+ ..add(7519)
+ ..add(7520)
+ ..add(7521)
+ ..add(7522)
+ ..add(7523)
+ ..add(7524)
+ ..add(7525)
+ ..add(7526)
+ ..add(7527)
+ ..add(7528)
+ ..add(7529)
+ ..add(7530)
+ ..add(7531)
+ ..add(7532)
+ ..add(7533)
+ ..add(7534)
+ ..add(7535)
+ ..add(7536)
+ ..add(7537)
+ ..add(7538)
+ ..add(7539)
+ ..add(7540)
+ ..add(7541)
+ ..add(7542)
+ ..add(7543)
+ ..add(7544)
+ ..add(7545)
+ ..add(7546)
+ ..add(7547)
+ ..add(7548)
+ ..add(7549)
+ ..add(7550)
+ ..add(7551)
+ ..add(7552)
+ ..add(7553)
+ ..add(7554)
+ ..add(7555)
+ ..add(7556)
+ ..add(7557)
+ ..add(7558)
+ ..add(7559)
+ ..add(7560)
+ ..add(7561)
+ ..add(7562)
+ ..add(7563)
+ ..add(7564)
+ ..add(7565)
+ ..add(7566)
+ ..add(7567)
+ ..add(7568)
+ ..add(7569)
+ ..add(7570)
+ ..add(7571)
+ ..add(7572)
+ ..add(7573)
+ ..add(7574)
+ ..add(7575)
+ ..add(7576)
+ ..add(7577)
+ ..add(7578)
+ ..add(7579)
+ ..add(7580)
+ ..add(7581)
+ ..add(7582)
+ ..add(7583)
+ ..add(7584)
+ ..add(7585)
+ ..add(7586)
+ ..add(7587)
+ ..add(7588)
+ ..add(7589)
+ ..add(7590)
+ ..add(7591)
+ ..add(7592)
+ ..add(7593)
+ ..add(7594)
+ ..add(7595)
+ ..add(7596)
+ ..add(7597)
+ ..add(7598)
+ ..add(7599)
+ ..add(7600)
+ ..add(7601)
+ ..add(7602)
+ ..add(7603)
+ ..add(7604)
+ ..add(7605)
+ ..add(7606)
+ ..add(7607)
+ ..add(7608)
+ ..add(7609)
+ ..add(7610)
+ ..add(7611)
+ ..add(7612)
+ ..add(7613)
+ ..add(7614)
+ ..add(7615)
+ ..add(7616)
+ ..add(7617)
+ ..add(7618)
+ ..add(7619)
+ ..add(7620)
+ ..add(7621)
+ ..add(7622)
+ ..add(7623)
+ ..add(7624)
+ ..add(7625)
+ ..add(7626)
+ ..add(7627)
+ ..add(7628)
+ ..add(7629)
+ ..add(7630)
+ ..add(7631)
+ ..add(7632)
+ ..add(7633)
+ ..add(7634)
+ ..add(7635)
+ ..add(7636)
+ ..add(7637)
+ ..add(7638)
+ ..add(7639)
+ ..add(7640)
+ ..add(7641)
+ ..add(7642)
+ ..add(7643)
+ ..add(7644)
+ ..add(7645)
+ ..add(7646)
+ ..add(7647)
+ ..add(7648)
+ ..add(7649)
+ ..add(7650)
+ ..add(7651)
+ ..add(7652)
+ ..add(7653)
+ ..add(7654)
+ ..add(7655)
+ ..add(7656)
+ ..add(7657)
+ ..add(7658)
+ ..add(7659)
+ ..add(7660)
+ ..add(7661)
+ ..add(7662)
+ ..add(7663)
+ ..add(7664)
+ ..add(7665)
+ ..add(7666)
+ ..add(7667)
+ ..add(7668)
+ ..add(7669)
+ ..add(7670)
+ ..add(7671)
+ ..add(7672)
+ ..add(7673)
+ ..add(7674)
+ ..add(7675)
+ ..add(7676)
+ ..add(7677)
+ ..add(7678)
+ ..add(7679)
+ ..add(7680)
+ ..add(7681)
+ ..add(7682)
+ ..add(7683)
+ ..add(7684)
+ ..add(7685)
+ ..add(7686)
+ ..add(7687)
+ ..add(7688)
+ ..add(7689)
+ ..add(7690)
+ ..add(7691)
+ ..add(7692)
+ ..add(7693)
+ ..add(7694)
+ ..add(7695)
+ ..add(7696)
+ ..add(7697)
+ ..add(7698)
+ ..add(7699)
+ ..add(7700)
+ ..add(7701)
+ ..add(7702)
+ ..add(7703)
+ ..add(7704)
+ ..add(7705)
+ ..add(7706)
+ ..add(7707)
+ ..add(7708)
+ ..add(7709)
+ ..add(7710)
+ ..add(7711)
+ ..add(7712)
+ ..add(7713)
+ ..add(7714)
+ ..add(7715)
+ ..add(7716)
+ ..add(7717)
+ ..add(7718)
+ ..add(7719)
+ ..add(7720)
+ ..add(7721)
+ ..add(7722)
+ ..add(7723)
+ ..add(7724)
+ ..add(7725)
+ ..add(7726)
+ ..add(7727)
+ ..add(7728)
+ ..add(7729)
+ ..add(7730)
+ ..add(7731)
+ ..add(7732)
+ ..add(7733)
+ ..add(7734)
+ ..add(7735)
+ ..add(7736)
+ ..add(7737)
+ ..add(7738)
+ ..add(7739)
+ ..add(7740)
+ ..add(7741)
+ ..add(7742)
+ ..add(7743)
+ ..add(7744)
+ ..add(7745)
+ ..add(7746)
+ ..add(7747)
+ ..add(7748)
+ ..add(7749)
+ ..add(7750)
+ ..add(7751)
+ ..add(7752)
+ ..add(7753)
+ ..add(7754)
+ ..add(7755)
+ ..add(7756)
+ ..add(7757)
+ ..add(7758)
+ ..add(7759)
+ ..add(7760)
+ ..add(7761)
+ ..add(7762)
+ ..add(7763)
+ ..add(7764)
+ ..add(7765)
+ ..add(7766)
+ ..add(7767)
+ ..add(7768)
+ ..add(7769)
+ ..add(7770)
+ ..add(7771)
+ ..add(7772)
+ ..add(7773)
+ ..add(7774)
+ ..add(7775)
+ ..add(7776)
+ ..add(7777)
+ ..add(7778)
+ ..add(7779)
+ ..add(7780)
+ ..add(7781)
+ ..add(7782)
+ ..add(7783)
+ ..add(7784)
+ ..add(7785)
+ ..add(7786)
+ ..add(7787)
+ ..add(7788)
+ ..add(7789)
+ ..add(7790)
+ ..add(7791)
+ ..add(7792)
+ ..add(7793)
+ ..add(7794)
+ ..add(7795)
+ ..add(7796)
+ ..add(7797)
+ ..add(7798)
+ ..add(7799)
+ ..add(7800)
+ ..add(7801)
+ ..add(7802)
+ ..add(7803)
+ ..add(7804)
+ ..add(7805)
+ ..add(7806)
+ ..add(7807)
+ ..add(7808)
+ ..add(7809)
+ ..add(7810)
+ ..add(7811)
+ ..add(7812)
+ ..add(7813)
+ ..add(7814)
+ ..add(7815)
+ ..add(7816)
+ ..add(7817)
+ ..add(7818)
+ ..add(7819)
+ ..add(7820)
+ ..add(7821)
+ ..add(7822)
+ ..add(7823)
+ ..add(7824)
+ ..add(7825)
+ ..add(7826)
+ ..add(7827)
+ ..add(7828)
+ ..add(7829)
+ ..add(7830)
+ ..add(7831)
+ ..add(7832)
+ ..add(7833)
+ ..add(7834)
+ ..add(7835)
+ ..add(7836)
+ ..add(7837)
+ ..add(7838)
+ ..add(7839)
+ ..add(7840)
+ ..add(7841)
+ ..add(7842)
+ ..add(7843)
+ ..add(7844)
+ ..add(7845)
+ ..add(7846)
+ ..add(7847)
+ ..add(7848)
+ ..add(7849)
+ ..add(7850)
+ ..add(7851)
+ ..add(7852)
+ ..add(7853)
+ ..add(7854)
+ ..add(7855)
+ ..add(7856)
+ ..add(7857)
+ ..add(7858)
+ ..add(7859)
+ ..add(7860)
+ ..add(7861)
+ ..add(7862)
+ ..add(7863)
+ ..add(7864)
+ ..add(7865)
+ ..add(7866)
+ ..add(7867)
+ ..add(7868)
+ ..add(7869)
+ ..add(7870)
+ ..add(7871)
+ ..add(7872)
+ ..add(7873)
+ ..add(7874)
+ ..add(7875)
+ ..add(7876)
+ ..add(7877)
+ ..add(7878)
+ ..add(7879)
+ ..add(7880)
+ ..add(7881)
+ ..add(7882)
+ ..add(7883)
+ ..add(7884)
+ ..add(7885)
+ ..add(7886)
+ ..add(7887)
+ ..add(7888)
+ ..add(7889)
+ ..add(7890)
+ ..add(7891)
+ ..add(7892)
+ ..add(7893)
+ ..add(7894)
+ ..add(7895)
+ ..add(7896)
+ ..add(7897)
+ ..add(7898)
+ ..add(7899)
+ ..add(7900)
+ ..add(7901)
+ ..add(7902)
+ ..add(7903)
+ ..add(7904)
+ ..add(7905)
+ ..add(7906)
+ ..add(7907)
+ ..add(7908)
+ ..add(7909)
+ ..add(7910)
+ ..add(7911)
+ ..add(7912)
+ ..add(7913)
+ ..add(7914)
+ ..add(7915)
+ ..add(7916)
+ ..add(7917)
+ ..add(7918)
+ ..add(7919)
+ ..add(7920)
+ ..add(7921)
+ ..add(7922)
+ ..add(7923)
+ ..add(7924)
+ ..add(7925)
+ ..add(7926)
+ ..add(7927)
+ ..add(7928)
+ ..add(7929)
+ ..add(7930)
+ ..add(7931)
+ ..add(7932)
+ ..add(7933)
+ ..add(7934)
+ ..add(7935)
+ ..add(7936)
+ ..add(7937)
+ ..add(7938)
+ ..add(7939)
+ ..add(7940)
+ ..add(7941)
+ ..add(7942)
+ ..add(7943)
+ ..add(7944)
+ ..add(7945)
+ ..add(7946)
+ ..add(7947)
+ ..add(7948)
+ ..add(7949)
+ ..add(7950)
+ ..add(7951)
+ ..add(7952)
+ ..add(7953)
+ ..add(7954)
+ ..add(7955)
+ ..add(7956)
+ ..add(7957)
+ ..add(7958)
+ ..add(7959)
+ ..add(7960)
+ ..add(7961)
+ ..add(7962)
+ ..add(7963)
+ ..add(7964)
+ ..add(7965)
+ ..add(7966)
+ ..add(7967)
+ ..add(7968)
+ ..add(7969)
+ ..add(7970)
+ ..add(7971)
+ ..add(7972)
+ ..add(7973)
+ ..add(7974)
+ ..add(7975)
+ ..add(7976)
+ ..add(7977)
+ ..add(7978)
+ ..add(7979)
+ ..add(7980)
+ ..add(7981)
+ ..add(7982)
+ ..add(7983)
+ ..add(7984)
+ ..add(7985)
+ ..add(7986)
+ ..add(7987)
+ ..add(7988)
+ ..add(7989)
+ ..add(7990)
+ ..add(7991)
+ ..add(7992)
+ ..add(7993)
+ ..add(7994)
+ ..add(7995)
+ ..add(7996)
+ ..add(7997)
+ ..add(7998)
+ ..add(7999)
+ ..add(8000)
+ ..add(8001)
+ ..add(8002)
+ ..add(8003)
+ ..add(8004)
+ ..add(8005)
+ ..add(8006)
+ ..add(8007)
+ ..add(8008)
+ ..add(8009)
+ ..add(8010)
+ ..add(8011)
+ ..add(8012)
+ ..add(8013)
+ ..add(8014)
+ ..add(8015)
+ ..add(8016)
+ ..add(8017)
+ ..add(8018)
+ ..add(8019)
+ ..add(8020)
+ ..add(8021)
+ ..add(8022)
+ ..add(8023)
+ ..add(8024)
+ ..add(8025)
+ ..add(8026)
+ ..add(8027)
+ ..add(8028)
+ ..add(8029)
+ ..add(8030)
+ ..add(8031)
+ ..add(8032)
+ ..add(8033)
+ ..add(8034)
+ ..add(8035)
+ ..add(8036)
+ ..add(8037)
+ ..add(8038)
+ ..add(8039)
+ ..add(8040)
+ ..add(8041)
+ ..add(8042)
+ ..add(8043)
+ ..add(8044)
+ ..add(8045)
+ ..add(8046)
+ ..add(8047)
+ ..add(8048)
+ ..add(8049)
+ ..add(8050)
+ ..add(8051)
+ ..add(8052)
+ ..add(8053)
+ ..add(8054)
+ ..add(8055)
+ ..add(8056)
+ ..add(8057)
+ ..add(8058)
+ ..add(8059)
+ ..add(8060)
+ ..add(8061)
+ ..add(8062)
+ ..add(8063)
+ ..add(8064)
+ ..add(8065)
+ ..add(8066)
+ ..add(8067)
+ ..add(8068)
+ ..add(8069)
+ ..add(8070)
+ ..add(8071)
+ ..add(8072)
+ ..add(8073)
+ ..add(8074)
+ ..add(8075)
+ ..add(8076)
+ ..add(8077)
+ ..add(8078)
+ ..add(8079)
+ ..add(8080)
+ ..add(8081)
+ ..add(8082)
+ ..add(8083)
+ ..add(8084)
+ ..add(8085)
+ ..add(8086)
+ ..add(8087)
+ ..add(8088)
+ ..add(8089)
+ ..add(8090)
+ ..add(8091)
+ ..add(8092)
+ ..add(8093)
+ ..add(8094)
+ ..add(8095)
+ ..add(8096)
+ ..add(8097)
+ ..add(8098)
+ ..add(8099)
+ ..add(8100)
+ ..add(8101)
+ ..add(8102)
+ ..add(8103)
+ ..add(8104)
+ ..add(8105)
+ ..add(8106)
+ ..add(8107)
+ ..add(8108)
+ ..add(8109)
+ ..add(8110)
+ ..add(8111)
+ ..add(8112)
+ ..add(8113)
+ ..add(8114)
+ ..add(8115)
+ ..add(8116)
+ ..add(8117)
+ ..add(8118)
+ ..add(8119)
+ ..add(8120)
+ ..add(8121)
+ ..add(8122)
+ ..add(8123)
+ ..add(8124)
+ ..add(8125)
+ ..add(8126)
+ ..add(8127)
+ ..add(8128)
+ ..add(8129)
+ ..add(8130)
+ ..add(8131)
+ ..add(8132)
+ ..add(8133)
+ ..add(8134)
+ ..add(8135)
+ ..add(8136)
+ ..add(8137)
+ ..add(8138)
+ ..add(8139)
+ ..add(8140)
+ ..add(8141)
+ ..add(8142)
+ ..add(8143)
+ ..add(8144)
+ ..add(8145)
+ ..add(8146)
+ ..add(8147)
+ ..add(8148)
+ ..add(8149)
+ ..add(8150)
+ ..add(8151)
+ ..add(8152)
+ ..add(8153)
+ ..add(8154)
+ ..add(8155)
+ ..add(8156)
+ ..add(8157)
+ ..add(8158)
+ ..add(8159)
+ ..add(8160)
+ ..add(8161)
+ ..add(8162)
+ ..add(8163)
+ ..add(8164)
+ ..add(8165)
+ ..add(8166)
+ ..add(8167)
+ ..add(8168)
+ ..add(8169)
+ ..add(8170)
+ ..add(8171)
+ ..add(8172)
+ ..add(8173)
+ ..add(8174)
+ ..add(8175)
+ ..add(8176)
+ ..add(8177)
+ ..add(8178)
+ ..add(8179)
+ ..add(8180)
+ ..add(8181)
+ ..add(8182)
+ ..add(8183)
+ ..add(8184)
+ ..add(8185)
+ ..add(8186)
+ ..add(8187)
+ ..add(8188)
+ ..add(8189)
+ ..add(8190)
+ ..add(8191)
+ ..add(8192)
+ ..add(8193)
+ ..add(8194)
+ ..add(8195)
+ ..add(8196)
+ ..add(8197)
+ ..add(8198)
+ ..add(8199)
+ ..add(8200)
+ ..add(8201)
+ ..add(8202)
+ ..add(8203)
+ ..add(8204)
+ ..add(8205)
+ ..add(8206)
+ ..add(8207)
+ ..add(8208)
+ ..add(8209)
+ ..add(8210)
+ ..add(8211)
+ ..add(8212)
+ ..add(8213)
+ ..add(8214)
+ ..add(8215)
+ ..add(8216)
+ ..add(8217)
+ ..add(8218)
+ ..add(8219)
+ ..add(8220)
+ ..add(8221)
+ ..add(8222)
+ ..add(8223)
+ ..add(8224)
+ ..add(8225)
+ ..add(8226)
+ ..add(8227)
+ ..add(8228)
+ ..add(8229)
+ ..add(8230)
+ ..add(8231)
+ ..add(8232)
+ ..add(8233)
+ ..add(8234)
+ ..add(8235)
+ ..add(8236)
+ ..add(8237)
+ ..add(8238)
+ ..add(8239)
+ ..add(8240)
+ ..add(8241)
+ ..add(8242)
+ ..add(8243)
+ ..add(8244)
+ ..add(8245)
+ ..add(8246)
+ ..add(8247)
+ ..add(8248)
+ ..add(8249)
+ ..add(8250)
+ ..add(8251)
+ ..add(8252)
+ ..add(8253)
+ ..add(8254)
+ ..add(8255)
+ ..add(8256)
+ ..add(8257)
+ ..add(8258)
+ ..add(8259)
+ ..add(8260)
+ ..add(8261)
+ ..add(8262)
+ ..add(8263)
+ ..add(8264)
+ ..add(8265)
+ ..add(8266)
+ ..add(8267)
+ ..add(8268)
+ ..add(8269)
+ ..add(8270)
+ ..add(8271)
+ ..add(8272)
+ ..add(8273)
+ ..add(8274)
+ ..add(8275)
+ ..add(8276)
+ ..add(8277)
+ ..add(8278)
+ ..add(8279)
+ ..add(8280)
+ ..add(8281)
+ ..add(8282)
+ ..add(8283)
+ ..add(8284)
+ ..add(8285)
+ ..add(8286)
+ ..add(8287)
+ ..add(8288)
+ ..add(8289)
+ ..add(8290)
+ ..add(8291)
+ ..add(8292)
+ ..add(8293)
+ ..add(8294)
+ ..add(8295)
+ ..add(8296)
+ ..add(8297)
+ ..add(8298)
+ ..add(8299)
+ ..add(8300)
+ ..add(8301)
+ ..add(8302)
+ ..add(8303)
+ ..add(8304)
+ ..add(8305)
+ ..add(8306)
+ ..add(8307)
+ ..add(8308)
+ ..add(8309)
+ ..add(8310)
+ ..add(8311)
+ ..add(8312)
+ ..add(8313)
+ ..add(8314)
+ ..add(8315)
+ ..add(8316)
+ ..add(8317)
+ ..add(8318)
+ ..add(8319)
+ ..add(8320)
+ ..add(8321)
+ ..add(8322)
+ ..add(8323)
+ ..add(8324)
+ ..add(8325)
+ ..add(8326)
+ ..add(8327)
+ ..add(8328)
+ ..add(8329)
+ ..add(8330)
+ ..add(8331)
+ ..add(8332)
+ ..add(8333)
+ ..add(8334)
+ ..add(8335)
+ ..add(8336)
+ ..add(8337)
+ ..add(8338)
+ ..add(8339)
+ ..add(8340)
+ ..add(8341)
+ ..add(8342)
+ ..add(8343)
+ ..add(8344)
+ ..add(8345)
+ ..add(8346)
+ ..add(8347)
+ ..add(8348)
+ ..add(8349)
+ ..add(8350)
+ ..add(8351)
+ ..add(8352)
+ ..add(8353)
+ ..add(8354)
+ ..add(8355)
+ ..add(8356)
+ ..add(8357)
+ ..add(8358)
+ ..add(8359)
+ ..add(8360)
+ ..add(8361)
+ ..add(8362)
+ ..add(8363)
+ ..add(8364)
+ ..add(8365)
+ ..add(8366)
+ ..add(8367)
+ ..add(8368)
+ ..add(8369)
+ ..add(8370)
+ ..add(8371)
+ ..add(8372)
+ ..add(8373)
+ ..add(8374)
+ ..add(8375)
+ ..add(8376)
+ ..add(8377)
+ ..add(8378)
+ ..add(8379)
+ ..add(8380)
+ ..add(8381)
+ ..add(8382)
+ ..add(8383)
+ ..add(8384)
+ ..add(8385)
+ ..add(8386)
+ ..add(8387)
+ ..add(8388)
+ ..add(8389)
+ ..add(8390)
+ ..add(8391)
+ ..add(8392)
+ ..add(8393)
+ ..add(8394)
+ ..add(8395)
+ ..add(8396)
+ ..add(8397)
+ ..add(8398)
+ ..add(8399)
+ ..add(8400)
+ ..add(8401)
+ ..add(8402)
+ ..add(8403)
+ ..add(8404)
+ ..add(8405)
+ ..add(8406)
+ ..add(8407)
+ ..add(8408)
+ ..add(8409)
+ ..add(8410)
+ ..add(8411)
+ ..add(8412)
+ ..add(8413)
+ ..add(8414)
+ ..add(8415)
+ ..add(8416)
+ ..add(8417)
+ ..add(8418)
+ ..add(8419)
+ ..add(8420)
+ ..add(8421)
+ ..add(8422)
+ ..add(8423)
+ ..add(8424)
+ ..add(8425)
+ ..add(8426)
+ ..add(8427)
+ ..add(8428)
+ ..add(8429)
+ ..add(8430)
+ ..add(8431)
+ ..add(8432)
+ ..add(8433)
+ ..add(8434)
+ ..add(8435)
+ ..add(8436)
+ ..add(8437)
+ ..add(8438)
+ ..add(8439)
+ ..add(8440)
+ ..add(8441)
+ ..add(8442)
+ ..add(8443)
+ ..add(8444)
+ ..add(8445)
+ ..add(8446)
+ ..add(8447)
+ ..add(8448)
+ ..add(8449)
+ ..add(8450)
+ ..add(8451)
+ ..add(8452)
+ ..add(8453)
+ ..add(8454)
+ ..add(8455)
+ ..add(8456)
+ ..add(8457)
+ ..add(8458)
+ ..add(8459)
+ ..add(8460)
+ ..add(8461)
+ ..add(8462)
+ ..add(8463)
+ ..add(8464)
+ ..add(8465)
+ ..add(8466)
+ ..add(8467)
+ ..add(8468)
+ ..add(8469)
+ ..add(8470)
+ ..add(8471)
+ ..add(8472)
+ ..add(8473)
+ ..add(8474)
+ ..add(8475)
+ ..add(8476)
+ ..add(8477)
+ ..add(8478)
+ ..add(8479)
+ ..add(8480)
+ ..add(8481)
+ ..add(8482)
+ ..add(8483)
+ ..add(8484)
+ ..add(8485)
+ ..add(8486)
+ ..add(8487)
+ ..add(8488)
+ ..add(8489)
+ ..add(8490)
+ ..add(8491)
+ ..add(8492)
+ ..add(8493)
+ ..add(8494)
+ ..add(8495)
+ ..add(8496)
+ ..add(8497)
+ ..add(8498)
+ ..add(8499)
+ ..add(8500)
+ ..add(8501)
+ ..add(8502)
+ ..add(8503)
+ ..add(8504)
+ ..add(8505)
+ ..add(8506)
+ ..add(8507)
+ ..add(8508)
+ ..add(8509)
+ ..add(8510)
+ ..add(8511)
+ ..add(8512)
+ ..add(8513)
+ ..add(8514)
+ ..add(8515)
+ ..add(8516)
+ ..add(8517)
+ ..add(8518)
+ ..add(8519)
+ ..add(8520)
+ ..add(8521)
+ ..add(8522)
+ ..add(8523)
+ ..add(8524)
+ ..add(8525)
+ ..add(8526)
+ ..add(8527)
+ ..add(8528)
+ ..add(8529)
+ ..add(8530)
+ ..add(8531)
+ ..add(8532)
+ ..add(8533)
+ ..add(8534)
+ ..add(8535)
+ ..add(8536)
+ ..add(8537)
+ ..add(8538)
+ ..add(8539)
+ ..add(8540)
+ ..add(8541)
+ ..add(8542)
+ ..add(8543)
+ ..add(8544)
+ ..add(8545)
+ ..add(8546)
+ ..add(8547)
+ ..add(8548)
+ ..add(8549)
+ ..add(8550)
+ ..add(8551)
+ ..add(8552)
+ ..add(8553)
+ ..add(8554)
+ ..add(8555)
+ ..add(8556)
+ ..add(8557)
+ ..add(8558)
+ ..add(8559)
+ ..add(8560)
+ ..add(8561)
+ ..add(8562)
+ ..add(8563)
+ ..add(8564)
+ ..add(8565)
+ ..add(8566)
+ ..add(8567)
+ ..add(8568)
+ ..add(8569)
+ ..add(8570)
+ ..add(8571)
+ ..add(8572)
+ ..add(8573)
+ ..add(8574)
+ ..add(8575)
+ ..add(8576)
+ ..add(8577)
+ ..add(8578)
+ ..add(8579)
+ ..add(8580)
+ ..add(8581)
+ ..add(8582)
+ ..add(8583)
+ ..add(8584)
+ ..add(8585)
+ ..add(8586)
+ ..add(8587)
+ ..add(8588)
+ ..add(8589)
+ ..add(8590)
+ ..add(8591)
+ ..add(8592)
+ ..add(8593)
+ ..add(8594)
+ ..add(8595)
+ ..add(8596)
+ ..add(8597)
+ ..add(8598)
+ ..add(8599)
+ ..add(8600)
+ ..add(8601)
+ ..add(8602)
+ ..add(8603)
+ ..add(8604)
+ ..add(8605)
+ ..add(8606)
+ ..add(8607)
+ ..add(8608)
+ ..add(8609)
+ ..add(8610)
+ ..add(8611)
+ ..add(8612)
+ ..add(8613)
+ ..add(8614)
+ ..add(8615)
+ ..add(8616)
+ ..add(8617)
+ ..add(8618)
+ ..add(8619)
+ ..add(8620)
+ ..add(8621)
+ ..add(8622)
+ ..add(8623)
+ ..add(8624)
+ ..add(8625)
+ ..add(8626)
+ ..add(8627)
+ ..add(8628)
+ ..add(8629)
+ ..add(8630)
+ ..add(8631)
+ ..add(8632)
+ ..add(8633)
+ ..add(8634)
+ ..add(8635)
+ ..add(8636)
+ ..add(8637)
+ ..add(8638)
+ ..add(8639)
+ ..add(8640)
+ ..add(8641)
+ ..add(8642)
+ ..add(8643)
+ ..add(8644)
+ ..add(8645)
+ ..add(8646)
+ ..add(8647)
+ ..add(8648)
+ ..add(8649)
+ ..add(8650)
+ ..add(8651)
+ ..add(8652)
+ ..add(8653)
+ ..add(8654)
+ ..add(8655)
+ ..add(8656)
+ ..add(8657)
+ ..add(8658)
+ ..add(8659)
+ ..add(8660)
+ ..add(8661)
+ ..add(8662)
+ ..add(8663)
+ ..add(8664)
+ ..add(8665)
+ ..add(8666)
+ ..add(8667)
+ ..add(8668)
+ ..add(8669)
+ ..add(8670)
+ ..add(8671)
+ ..add(8672)
+ ..add(8673)
+ ..add(8674)
+ ..add(8675)
+ ..add(8676)
+ ..add(8677)
+ ..add(8678)
+ ..add(8679)
+ ..add(8680)
+ ..add(8681)
+ ..add(8682)
+ ..add(8683)
+ ..add(8684)
+ ..add(8685)
+ ..add(8686)
+ ..add(8687)
+ ..add(8688)
+ ..add(8689)
+ ..add(8690)
+ ..add(8691)
+ ..add(8692)
+ ..add(8693)
+ ..add(8694)
+ ..add(8695)
+ ..add(8696)
+ ..add(8697)
+ ..add(8698)
+ ..add(8699)
+ ..add(8700)
+ ..add(8701)
+ ..add(8702)
+ ..add(8703)
+ ..add(8704)
+ ..add(8705)
+ ..add(8706)
+ ..add(8707)
+ ..add(8708)
+ ..add(8709)
+ ..add(8710)
+ ..add(8711)
+ ..add(8712)
+ ..add(8713)
+ ..add(8714)
+ ..add(8715)
+ ..add(8716)
+ ..add(8717)
+ ..add(8718)
+ ..add(8719)
+ ..add(8720)
+ ..add(8721)
+ ..add(8722)
+ ..add(8723)
+ ..add(8724)
+ ..add(8725)
+ ..add(8726)
+ ..add(8727)
+ ..add(8728)
+ ..add(8729)
+ ..add(8730)
+ ..add(8731)
+ ..add(8732)
+ ..add(8733)
+ ..add(8734)
+ ..add(8735)
+ ..add(8736)
+ ..add(8737)
+ ..add(8738)
+ ..add(8739)
+ ..add(8740)
+ ..add(8741)
+ ..add(8742)
+ ..add(8743)
+ ..add(8744)
+ ..add(8745)
+ ..add(8746)
+ ..add(8747)
+ ..add(8748)
+ ..add(8749)
+ ..add(8750)
+ ..add(8751)
+ ..add(8752)
+ ..add(8753)
+ ..add(8754)
+ ..add(8755)
+ ..add(8756)
+ ..add(8757)
+ ..add(8758)
+ ..add(8759)
+ ..add(8760)
+ ..add(8761)
+ ..add(8762)
+ ..add(8763)
+ ..add(8764)
+ ..add(8765)
+ ..add(8766)
+ ..add(8767)
+ ..add(8768)
+ ..add(8769)
+ ..add(8770)
+ ..add(8771)
+ ..add(8772)
+ ..add(8773)
+ ..add(8774)
+ ..add(8775)
+ ..add(8776)
+ ..add(8777)
+ ..add(8778)
+ ..add(8779)
+ ..add(8780)
+ ..add(8781)
+ ..add(8782)
+ ..add(8783)
+ ..add(8784)
+ ..add(8785)
+ ..add(8786)
+ ..add(8787)
+ ..add(8788)
+ ..add(8789)
+ ..add(8790)
+ ..add(8791)
+ ..add(8792)
+ ..add(8793)
+ ..add(8794)
+ ..add(8795)
+ ..add(8796)
+ ..add(8797)
+ ..add(8798)
+ ..add(8799)
+ ..add(8800)
+ ..add(8801)
+ ..add(8802)
+ ..add(8803)
+ ..add(8804)
+ ..add(8805)
+ ..add(8806)
+ ..add(8807)
+ ..add(8808)
+ ..add(8809)
+ ..add(8810)
+ ..add(8811)
+ ..add(8812)
+ ..add(8813)
+ ..add(8814)
+ ..add(8815)
+ ..add(8816)
+ ..add(8817)
+ ..add(8818)
+ ..add(8819)
+ ..add(8820)
+ ..add(8821)
+ ..add(8822)
+ ..add(8823)
+ ..add(8824)
+ ..add(8825)
+ ..add(8826)
+ ..add(8827)
+ ..add(8828)
+ ..add(8829)
+ ..add(8830)
+ ..add(8831)
+ ..add(8832)
+ ..add(8833)
+ ..add(8834)
+ ..add(8835)
+ ..add(8836)
+ ..add(8837)
+ ..add(8838)
+ ..add(8839)
+ ..add(8840)
+ ..add(8841)
+ ..add(8842)
+ ..add(8843)
+ ..add(8844)
+ ..add(8845)
+ ..add(8846)
+ ..add(8847)
+ ..add(8848)
+ ..add(8849)
+ ..add(8850)
+ ..add(8851)
+ ..add(8852)
+ ..add(8853)
+ ..add(8854)
+ ..add(8855)
+ ..add(8856)
+ ..add(8857)
+ ..add(8858)
+ ..add(8859)
+ ..add(8860)
+ ..add(8861)
+ ..add(8862)
+ ..add(8863)
+ ..add(8864)
+ ..add(8865)
+ ..add(8866)
+ ..add(8867)
+ ..add(8868)
+ ..add(8869)
+ ..add(8870)
+ ..add(8871)
+ ..add(8872)
+ ..add(8873)
+ ..add(8874)
+ ..add(8875)
+ ..add(8876)
+ ..add(8877)
+ ..add(8878)
+ ..add(8879)
+ ..add(8880)
+ ..add(8881)
+ ..add(8882)
+ ..add(8883)
+ ..add(8884)
+ ..add(8885)
+ ..add(8886)
+ ..add(8887)
+ ..add(8888)
+ ..add(8889)
+ ..add(8890)
+ ..add(8891)
+ ..add(8892)
+ ..add(8893)
+ ..add(8894)
+ ..add(8895)
+ ..add(8896)
+ ..add(8897)
+ ..add(8898)
+ ..add(8899)
+ ..add(8900)
+ ..add(8901)
+ ..add(8902)
+ ..add(8903)
+ ..add(8904)
+ ..add(8905)
+ ..add(8906)
+ ..add(8907)
+ ..add(8908)
+ ..add(8909)
+ ..add(8910)
+ ..add(8911)
+ ..add(8912)
+ ..add(8913)
+ ..add(8914)
+ ..add(8915)
+ ..add(8916)
+ ..add(8917)
+ ..add(8918)
+ ..add(8919)
+ ..add(8920)
+ ..add(8921)
+ ..add(8922)
+ ..add(8923)
+ ..add(8924)
+ ..add(8925)
+ ..add(8926)
+ ..add(8927)
+ ..add(8928)
+ ..add(8929)
+ ..add(8930)
+ ..add(8931)
+ ..add(8932)
+ ..add(8933)
+ ..add(8934)
+ ..add(8935)
+ ..add(8936)
+ ..add(8937)
+ ..add(8938)
+ ..add(8939)
+ ..add(8940)
+ ..add(8941)
+ ..add(8942)
+ ..add(8943)
+ ..add(8944)
+ ..add(8945)
+ ..add(8946)
+ ..add(8947)
+ ..add(8948)
+ ..add(8949)
+ ..add(8950)
+ ..add(8951)
+ ..add(8952)
+ ..add(8953)
+ ..add(8954)
+ ..add(8955)
+ ..add(8956)
+ ..add(8957)
+ ..add(8958)
+ ..add(8959)
+ ..add(8960)
+ ..add(8961)
+ ..add(8962)
+ ..add(8963)
+ ..add(8964)
+ ..add(8965)
+ ..add(8966)
+ ..add(8967)
+ ..add(8968)
+ ..add(8969)
+ ..add(8970)
+ ..add(8971)
+ ..add(8972)
+ ..add(8973)
+ ..add(8974)
+ ..add(8975)
+ ..add(8976)
+ ..add(8977)
+ ..add(8978)
+ ..add(8979)
+ ..add(8980)
+ ..add(8981)
+ ..add(8982)
+ ..add(8983)
+ ..add(8984)
+ ..add(8985)
+ ..add(8986)
+ ..add(8987)
+ ..add(8988)
+ ..add(8989)
+ ..add(8990)
+ ..add(8991)
+ ..add(8992)
+ ..add(8993)
+ ..add(8994)
+ ..add(8995)
+ ..add(8996)
+ ..add(8997)
+ ..add(8998)
+ ..add(8999)
+ ..add(9000)
+ ..add(9001)
+ ..add(9002)
+ ..add(9003)
+ ..add(9004)
+ ..add(9005)
+ ..add(9006)
+ ..add(9007)
+ ..add(9008)
+ ..add(9009)
+ ..add(9010)
+ ..add(9011)
+ ..add(9012)
+ ..add(9013)
+ ..add(9014)
+ ..add(9015)
+ ..add(9016)
+ ..add(9017)
+ ..add(9018)
+ ..add(9019)
+ ..add(9020)
+ ..add(9021)
+ ..add(9022)
+ ..add(9023)
+ ..add(9024)
+ ..add(9025)
+ ..add(9026)
+ ..add(9027)
+ ..add(9028)
+ ..add(9029)
+ ..add(9030)
+ ..add(9031)
+ ..add(9032)
+ ..add(9033)
+ ..add(9034)
+ ..add(9035)
+ ..add(9036)
+ ..add(9037)
+ ..add(9038)
+ ..add(9039)
+ ..add(9040)
+ ..add(9041)
+ ..add(9042)
+ ..add(9043)
+ ..add(9044)
+ ..add(9045)
+ ..add(9046)
+ ..add(9047)
+ ..add(9048)
+ ..add(9049)
+ ..add(9050)
+ ..add(9051)
+ ..add(9052)
+ ..add(9053)
+ ..add(9054)
+ ..add(9055)
+ ..add(9056)
+ ..add(9057)
+ ..add(9058)
+ ..add(9059)
+ ..add(9060)
+ ..add(9061)
+ ..add(9062)
+ ..add(9063)
+ ..add(9064)
+ ..add(9065)
+ ..add(9066)
+ ..add(9067)
+ ..add(9068)
+ ..add(9069)
+ ..add(9070)
+ ..add(9071)
+ ..add(9072)
+ ..add(9073)
+ ..add(9074)
+ ..add(9075)
+ ..add(9076)
+ ..add(9077)
+ ..add(9078)
+ ..add(9079)
+ ..add(9080)
+ ..add(9081)
+ ..add(9082)
+ ..add(9083)
+ ..add(9084)
+ ..add(9085)
+ ..add(9086)
+ ..add(9087)
+ ..add(9088)
+ ..add(9089)
+ ..add(9090)
+ ..add(9091)
+ ..add(9092)
+ ..add(9093)
+ ..add(9094)
+ ..add(9095)
+ ..add(9096)
+ ..add(9097)
+ ..add(9098)
+ ..add(9099)
+ ..add(9100)
+ ..add(9101)
+ ..add(9102)
+ ..add(9103)
+ ..add(9104)
+ ..add(9105)
+ ..add(9106)
+ ..add(9107)
+ ..add(9108)
+ ..add(9109)
+ ..add(9110)
+ ..add(9111)
+ ..add(9112)
+ ..add(9113)
+ ..add(9114)
+ ..add(9115)
+ ..add(9116)
+ ..add(9117)
+ ..add(9118)
+ ..add(9119)
+ ..add(9120)
+ ..add(9121)
+ ..add(9122)
+ ..add(9123)
+ ..add(9124)
+ ..add(9125)
+ ..add(9126)
+ ..add(9127)
+ ..add(9128)
+ ..add(9129)
+ ..add(9130)
+ ..add(9131)
+ ..add(9132)
+ ..add(9133)
+ ..add(9134)
+ ..add(9135)
+ ..add(9136)
+ ..add(9137)
+ ..add(9138)
+ ..add(9139)
+ ..add(9140)
+ ..add(9141)
+ ..add(9142)
+ ..add(9143)
+ ..add(9144)
+ ..add(9145)
+ ..add(9146)
+ ..add(9147)
+ ..add(9148)
+ ..add(9149)
+ ..add(9150)
+ ..add(9151)
+ ..add(9152)
+ ..add(9153)
+ ..add(9154)
+ ..add(9155)
+ ..add(9156)
+ ..add(9157)
+ ..add(9158)
+ ..add(9159)
+ ..add(9160)
+ ..add(9161)
+ ..add(9162)
+ ..add(9163)
+ ..add(9164)
+ ..add(9165)
+ ..add(9166)
+ ..add(9167)
+ ..add(9168)
+ ..add(9169)
+ ..add(9170)
+ ..add(9171)
+ ..add(9172)
+ ..add(9173)
+ ..add(9174)
+ ..add(9175)
+ ..add(9176)
+ ..add(9177)
+ ..add(9178)
+ ..add(9179)
+ ..add(9180)
+ ..add(9181)
+ ..add(9182)
+ ..add(9183)
+ ..add(9184)
+ ..add(9185)
+ ..add(9186)
+ ..add(9187)
+ ..add(9188)
+ ..add(9189)
+ ..add(9190)
+ ..add(9191)
+ ..add(9192)
+ ..add(9193)
+ ..add(9194)
+ ..add(9195)
+ ..add(9196)
+ ..add(9197)
+ ..add(9198)
+ ..add(9199)
+ ..add(9200)
+ ..add(9201)
+ ..add(9202)
+ ..add(9203)
+ ..add(9204)
+ ..add(9205)
+ ..add(9206)
+ ..add(9207)
+ ..add(9208)
+ ..add(9209)
+ ..add(9210)
+ ..add(9211)
+ ..add(9212)
+ ..add(9213)
+ ..add(9214)
+ ..add(9215)
+ ..add(9216)
+ ..add(9217)
+ ..add(9218)
+ ..add(9219)
+ ..add(9220)
+ ..add(9221)
+ ..add(9222)
+ ..add(9223)
+ ..add(9224)
+ ..add(9225)
+ ..add(9226)
+ ..add(9227)
+ ..add(9228)
+ ..add(9229)
+ ..add(9230)
+ ..add(9231)
+ ..add(9232)
+ ..add(9233)
+ ..add(9234)
+ ..add(9235)
+ ..add(9236)
+ ..add(9237)
+ ..add(9238)
+ ..add(9239)
+ ..add(9240)
+ ..add(9241)
+ ..add(9242)
+ ..add(9243)
+ ..add(9244)
+ ..add(9245)
+ ..add(9246)
+ ..add(9247)
+ ..add(9248)
+ ..add(9249)
+ ..add(9250)
+ ..add(9251)
+ ..add(9252)
+ ..add(9253)
+ ..add(9254)
+ ..add(9255)
+ ..add(9256)
+ ..add(9257)
+ ..add(9258)
+ ..add(9259)
+ ..add(9260)
+ ..add(9261)
+ ..add(9262)
+ ..add(9263)
+ ..add(9264)
+ ..add(9265)
+ ..add(9266)
+ ..add(9267)
+ ..add(9268)
+ ..add(9269)
+ ..add(9270)
+ ..add(9271)
+ ..add(9272)
+ ..add(9273)
+ ..add(9274)
+ ..add(9275)
+ ..add(9276)
+ ..add(9277)
+ ..add(9278)
+ ..add(9279)
+ ..add(9280)
+ ..add(9281)
+ ..add(9282)
+ ..add(9283)
+ ..add(9284)
+ ..add(9285)
+ ..add(9286)
+ ..add(9287)
+ ..add(9288)
+ ..add(9289)
+ ..add(9290)
+ ..add(9291)
+ ..add(9292)
+ ..add(9293)
+ ..add(9294)
+ ..add(9295)
+ ..add(9296)
+ ..add(9297)
+ ..add(9298)
+ ..add(9299)
+ ..add(9300)
+ ..add(9301)
+ ..add(9302)
+ ..add(9303)
+ ..add(9304)
+ ..add(9305)
+ ..add(9306)
+ ..add(9307)
+ ..add(9308)
+ ..add(9309)
+ ..add(9310)
+ ..add(9311)
+ ..add(9312)
+ ..add(9313)
+ ..add(9314)
+ ..add(9315)
+ ..add(9316)
+ ..add(9317)
+ ..add(9318)
+ ..add(9319)
+ ..add(9320)
+ ..add(9321)
+ ..add(9322)
+ ..add(9323)
+ ..add(9324)
+ ..add(9325)
+ ..add(9326)
+ ..add(9327)
+ ..add(9328)
+ ..add(9329)
+ ..add(9330)
+ ..add(9331)
+ ..add(9332)
+ ..add(9333)
+ ..add(9334)
+ ..add(9335)
+ ..add(9336)
+ ..add(9337)
+ ..add(9338)
+ ..add(9339)
+ ..add(9340)
+ ..add(9341)
+ ..add(9342)
+ ..add(9343)
+ ..add(9344)
+ ..add(9345)
+ ..add(9346)
+ ..add(9347)
+ ..add(9348)
+ ..add(9349)
+ ..add(9350)
+ ..add(9351)
+ ..add(9352)
+ ..add(9353)
+ ..add(9354)
+ ..add(9355)
+ ..add(9356)
+ ..add(9357)
+ ..add(9358)
+ ..add(9359)
+ ..add(9360)
+ ..add(9361)
+ ..add(9362)
+ ..add(9363)
+ ..add(9364)
+ ..add(9365)
+ ..add(9366)
+ ..add(9367)
+ ..add(9368)
+ ..add(9369)
+ ..add(9370)
+ ..add(9371)
+ ..add(9372)
+ ..add(9373)
+ ..add(9374)
+ ..add(9375)
+ ..add(9376)
+ ..add(9377)
+ ..add(9378)
+ ..add(9379)
+ ..add(9380)
+ ..add(9381)
+ ..add(9382)
+ ..add(9383)
+ ..add(9384)
+ ..add(9385)
+ ..add(9386)
+ ..add(9387)
+ ..add(9388)
+ ..add(9389)
+ ..add(9390)
+ ..add(9391)
+ ..add(9392)
+ ..add(9393)
+ ..add(9394)
+ ..add(9395)
+ ..add(9396)
+ ..add(9397)
+ ..add(9398)
+ ..add(9399)
+ ..add(9400)
+ ..add(9401)
+ ..add(9402)
+ ..add(9403)
+ ..add(9404)
+ ..add(9405)
+ ..add(9406)
+ ..add(9407)
+ ..add(9408)
+ ..add(9409)
+ ..add(9410)
+ ..add(9411)
+ ..add(9412)
+ ..add(9413)
+ ..add(9414)
+ ..add(9415)
+ ..add(9416)
+ ..add(9417)
+ ..add(9418)
+ ..add(9419)
+ ..add(9420)
+ ..add(9421)
+ ..add(9422)
+ ..add(9423)
+ ..add(9424)
+ ..add(9425)
+ ..add(9426)
+ ..add(9427)
+ ..add(9428)
+ ..add(9429)
+ ..add(9430)
+ ..add(9431)
+ ..add(9432)
+ ..add(9433)
+ ..add(9434)
+ ..add(9435)
+ ..add(9436)
+ ..add(9437)
+ ..add(9438)
+ ..add(9439)
+ ..add(9440)
+ ..add(9441)
+ ..add(9442)
+ ..add(9443)
+ ..add(9444)
+ ..add(9445)
+ ..add(9446)
+ ..add(9447)
+ ..add(9448)
+ ..add(9449)
+ ..add(9450)
+ ..add(9451)
+ ..add(9452)
+ ..add(9453)
+ ..add(9454)
+ ..add(9455)
+ ..add(9456)
+ ..add(9457)
+ ..add(9458)
+ ..add(9459)
+ ..add(9460)
+ ..add(9461)
+ ..add(9462)
+ ..add(9463)
+ ..add(9464)
+ ..add(9465)
+ ..add(9466)
+ ..add(9467)
+ ..add(9468)
+ ..add(9469)
+ ..add(9470)
+ ..add(9471)
+ ..add(9472)
+ ..add(9473)
+ ..add(9474)
+ ..add(9475)
+ ..add(9476)
+ ..add(9477)
+ ..add(9478)
+ ..add(9479)
+ ..add(9480)
+ ..add(9481)
+ ..add(9482)
+ ..add(9483)
+ ..add(9484)
+ ..add(9485)
+ ..add(9486)
+ ..add(9487)
+ ..add(9488)
+ ..add(9489)
+ ..add(9490)
+ ..add(9491)
+ ..add(9492)
+ ..add(9493)
+ ..add(9494)
+ ..add(9495)
+ ..add(9496)
+ ..add(9497)
+ ..add(9498)
+ ..add(9499)
+ ..add(9500)
+ ..add(9501)
+ ..add(9502)
+ ..add(9503)
+ ..add(9504)
+ ..add(9505)
+ ..add(9506)
+ ..add(9507)
+ ..add(9508)
+ ..add(9509)
+ ..add(9510)
+ ..add(9511)
+ ..add(9512)
+ ..add(9513)
+ ..add(9514)
+ ..add(9515)
+ ..add(9516)
+ ..add(9517)
+ ..add(9518)
+ ..add(9519)
+ ..add(9520)
+ ..add(9521)
+ ..add(9522)
+ ..add(9523)
+ ..add(9524)
+ ..add(9525)
+ ..add(9526)
+ ..add(9527)
+ ..add(9528)
+ ..add(9529)
+ ..add(9530)
+ ..add(9531)
+ ..add(9532)
+ ..add(9533)
+ ..add(9534)
+ ..add(9535)
+ ..add(9536)
+ ..add(9537)
+ ..add(9538)
+ ..add(9539)
+ ..add(9540)
+ ..add(9541)
+ ..add(9542)
+ ..add(9543)
+ ..add(9544)
+ ..add(9545)
+ ..add(9546)
+ ..add(9547)
+ ..add(9548)
+ ..add(9549)
+ ..add(9550)
+ ..add(9551)
+ ..add(9552)
+ ..add(9553)
+ ..add(9554)
+ ..add(9555)
+ ..add(9556)
+ ..add(9557)
+ ..add(9558)
+ ..add(9559)
+ ..add(9560)
+ ..add(9561)
+ ..add(9562)
+ ..add(9563)
+ ..add(9564)
+ ..add(9565)
+ ..add(9566)
+ ..add(9567)
+ ..add(9568)
+ ..add(9569)
+ ..add(9570)
+ ..add(9571)
+ ..add(9572)
+ ..add(9573)
+ ..add(9574)
+ ..add(9575)
+ ..add(9576)
+ ..add(9577)
+ ..add(9578)
+ ..add(9579)
+ ..add(9580)
+ ..add(9581)
+ ..add(9582)
+ ..add(9583)
+ ..add(9584)
+ ..add(9585)
+ ..add(9586)
+ ..add(9587)
+ ..add(9588)
+ ..add(9589)
+ ..add(9590)
+ ..add(9591)
+ ..add(9592)
+ ..add(9593)
+ ..add(9594)
+ ..add(9595)
+ ..add(9596)
+ ..add(9597)
+ ..add(9598)
+ ..add(9599)
+ ..add(9600)
+ ..add(9601)
+ ..add(9602)
+ ..add(9603)
+ ..add(9604)
+ ..add(9605)
+ ..add(9606)
+ ..add(9607)
+ ..add(9608)
+ ..add(9609)
+ ..add(9610)
+ ..add(9611)
+ ..add(9612)
+ ..add(9613)
+ ..add(9614)
+ ..add(9615)
+ ..add(9616)
+ ..add(9617)
+ ..add(9618)
+ ..add(9619)
+ ..add(9620)
+ ..add(9621)
+ ..add(9622)
+ ..add(9623)
+ ..add(9624)
+ ..add(9625)
+ ..add(9626)
+ ..add(9627)
+ ..add(9628)
+ ..add(9629)
+ ..add(9630)
+ ..add(9631)
+ ..add(9632)
+ ..add(9633)
+ ..add(9634)
+ ..add(9635)
+ ..add(9636)
+ ..add(9637)
+ ..add(9638)
+ ..add(9639)
+ ..add(9640)
+ ..add(9641)
+ ..add(9642)
+ ..add(9643)
+ ..add(9644)
+ ..add(9645)
+ ..add(9646)
+ ..add(9647)
+ ..add(9648)
+ ..add(9649)
+ ..add(9650)
+ ..add(9651)
+ ..add(9652)
+ ..add(9653)
+ ..add(9654)
+ ..add(9655)
+ ..add(9656)
+ ..add(9657)
+ ..add(9658)
+ ..add(9659)
+ ..add(9660)
+ ..add(9661)
+ ..add(9662)
+ ..add(9663)
+ ..add(9664)
+ ..add(9665)
+ ..add(9666)
+ ..add(9667)
+ ..add(9668)
+ ..add(9669)
+ ..add(9670)
+ ..add(9671)
+ ..add(9672)
+ ..add(9673)
+ ..add(9674)
+ ..add(9675)
+ ..add(9676)
+ ..add(9677)
+ ..add(9678)
+ ..add(9679)
+ ..add(9680)
+ ..add(9681)
+ ..add(9682)
+ ..add(9683)
+ ..add(9684)
+ ..add(9685)
+ ..add(9686)
+ ..add(9687)
+ ..add(9688)
+ ..add(9689)
+ ..add(9690)
+ ..add(9691)
+ ..add(9692)
+ ..add(9693)
+ ..add(9694)
+ ..add(9695)
+ ..add(9696)
+ ..add(9697)
+ ..add(9698)
+ ..add(9699)
+ ..add(9700)
+ ..add(9701)
+ ..add(9702)
+ ..add(9703)
+ ..add(9704)
+ ..add(9705)
+ ..add(9706)
+ ..add(9707)
+ ..add(9708)
+ ..add(9709)
+ ..add(9710)
+ ..add(9711)
+ ..add(9712)
+ ..add(9713)
+ ..add(9714)
+ ..add(9715)
+ ..add(9716)
+ ..add(9717)
+ ..add(9718)
+ ..add(9719)
+ ..add(9720)
+ ..add(9721)
+ ..add(9722)
+ ..add(9723)
+ ..add(9724)
+ ..add(9725)
+ ..add(9726)
+ ..add(9727)
+ ..add(9728)
+ ..add(9729)
+ ..add(9730)
+ ..add(9731)
+ ..add(9732)
+ ..add(9733)
+ ..add(9734)
+ ..add(9735)
+ ..add(9736)
+ ..add(9737)
+ ..add(9738)
+ ..add(9739)
+ ..add(9740)
+ ..add(9741)
+ ..add(9742)
+ ..add(9743)
+ ..add(9744)
+ ..add(9745)
+ ..add(9746)
+ ..add(9747)
+ ..add(9748)
+ ..add(9749)
+ ..add(9750)
+ ..add(9751)
+ ..add(9752)
+ ..add(9753)
+ ..add(9754)
+ ..add(9755)
+ ..add(9756)
+ ..add(9757)
+ ..add(9758)
+ ..add(9759)
+ ..add(9760)
+ ..add(9761)
+ ..add(9762)
+ ..add(9763)
+ ..add(9764)
+ ..add(9765)
+ ..add(9766)
+ ..add(9767)
+ ..add(9768)
+ ..add(9769)
+ ..add(9770)
+ ..add(9771)
+ ..add(9772)
+ ..add(9773)
+ ..add(9774)
+ ..add(9775)
+ ..add(9776)
+ ..add(9777)
+ ..add(9778)
+ ..add(9779)
+ ..add(9780)
+ ..add(9781)
+ ..add(9782)
+ ..add(9783)
+ ..add(9784)
+ ..add(9785)
+ ..add(9786)
+ ..add(9787)
+ ..add(9788)
+ ..add(9789)
+ ..add(9790)
+ ..add(9791)
+ ..add(9792)
+ ..add(9793)
+ ..add(9794)
+ ..add(9795)
+ ..add(9796)
+ ..add(9797)
+ ..add(9798)
+ ..add(9799)
+ ..add(9800)
+ ..add(9801)
+ ..add(9802)
+ ..add(9803)
+ ..add(9804)
+ ..add(9805)
+ ..add(9806)
+ ..add(9807)
+ ..add(9808)
+ ..add(9809)
+ ..add(9810)
+ ..add(9811)
+ ..add(9812)
+ ..add(9813)
+ ..add(9814)
+ ..add(9815)
+ ..add(9816)
+ ..add(9817)
+ ..add(9818)
+ ..add(9819)
+ ..add(9820)
+ ..add(9821)
+ ..add(9822)
+ ..add(9823)
+ ..add(9824)
+ ..add(9825)
+ ..add(9826)
+ ..add(9827)
+ ..add(9828)
+ ..add(9829)
+ ..add(9830)
+ ..add(9831)
+ ..add(9832)
+ ..add(9833)
+ ..add(9834)
+ ..add(9835)
+ ..add(9836)
+ ..add(9837)
+ ..add(9838)
+ ..add(9839)
+ ..add(9840)
+ ..add(9841)
+ ..add(9842)
+ ..add(9843)
+ ..add(9844)
+ ..add(9845)
+ ..add(9846)
+ ..add(9847)
+ ..add(9848)
+ ..add(9849)
+ ..add(9850)
+ ..add(9851)
+ ..add(9852)
+ ..add(9853)
+ ..add(9854)
+ ..add(9855)
+ ..add(9856)
+ ..add(9857)
+ ..add(9858)
+ ..add(9859)
+ ..add(9860)
+ ..add(9861)
+ ..add(9862)
+ ..add(9863)
+ ..add(9864)
+ ..add(9865)
+ ..add(9866)
+ ..add(9867)
+ ..add(9868)
+ ..add(9869)
+ ..add(9870)
+ ..add(9871)
+ ..add(9872)
+ ..add(9873)
+ ..add(9874)
+ ..add(9875)
+ ..add(9876)
+ ..add(9877)
+ ..add(9878)
+ ..add(9879)
+ ..add(9880)
+ ..add(9881)
+ ..add(9882)
+ ..add(9883)
+ ..add(9884)
+ ..add(9885)
+ ..add(9886)
+ ..add(9887)
+ ..add(9888)
+ ..add(9889)
+ ..add(9890)
+ ..add(9891)
+ ..add(9892)
+ ..add(9893)
+ ..add(9894)
+ ..add(9895)
+ ..add(9896)
+ ..add(9897)
+ ..add(9898)
+ ..add(9899)
+ ..add(9900)
+ ..add(9901)
+ ..add(9902)
+ ..add(9903)
+ ..add(9904)
+ ..add(9905)
+ ..add(9906)
+ ..add(9907)
+ ..add(9908)
+ ..add(9909)
+ ..add(9910)
+ ..add(9911)
+ ..add(9912)
+ ..add(9913)
+ ..add(9914)
+ ..add(9915)
+ ..add(9916)
+ ..add(9917)
+ ..add(9918)
+ ..add(9919)
+ ..add(9920)
+ ..add(9921)
+ ..add(9922)
+ ..add(9923)
+ ..add(9924)
+ ..add(9925)
+ ..add(9926)
+ ..add(9927)
+ ..add(9928)
+ ..add(9929)
+ ..add(9930)
+ ..add(9931)
+ ..add(9932)
+ ..add(9933)
+ ..add(9934)
+ ..add(9935)
+ ..add(9936)
+ ..add(9937)
+ ..add(9938)
+ ..add(9939)
+ ..add(9940)
+ ..add(9941)
+ ..add(9942)
+ ..add(9943)
+ ..add(9944)
+ ..add(9945)
+ ..add(9946)
+ ..add(9947)
+ ..add(9948)
+ ..add(9949)
+ ..add(9950)
+ ..add(9951)
+ ..add(9952)
+ ..add(9953)
+ ..add(9954)
+ ..add(9955)
+ ..add(9956)
+ ..add(9957)
+ ..add(9958)
+ ..add(9959)
+ ..add(9960)
+ ..add(9961)
+ ..add(9962)
+ ..add(9963)
+ ..add(9964)
+ ..add(9965)
+ ..add(9966)
+ ..add(9967)
+ ..add(9968)
+ ..add(9969)
+ ..add(9970)
+ ..add(9971)
+ ..add(9972)
+ ..add(9973)
+ ..add(9974)
+ ..add(9975)
+ ..add(9976)
+ ..add(9977)
+ ..add(9978)
+ ..add(9979)
+ ..add(9980)
+ ..add(9981)
+ ..add(9982)
+ ..add(9983)
+ ..add(9984)
+ ..add(9985)
+ ..add(9986)
+ ..add(9987)
+ ..add(9988)
+ ..add(9989)
+ ..add(9990)
+ ..add(9991)
+ ..add(9992)
+ ..add(9993)
+ ..add(9994)
+ ..add(9995)
+ ..add(9996)
+ ..add(9997)
+ ..add(9998)
+ ..add(9999)
+ ..add(10000)
+ ..add(10001)
+ ..add(10002)
+ ..add(10003)
+ ..add(10004)
+ ..add(10005)
+ ..add(10006)
+ ..add(10007)
+ ..add(10008)
+ ..add(10009)
+ ..add(10010)
+ ..add(10011)
+ ..add(10012)
+ ..add(10013)
+ ..add(10014)
+ ..add(10015)
+ ..add(10016)
+ ..add(10017)
+ ..add(10018)
+ ..add(10019)
+ ..add(10020)
+ ..add(10021)
+ ..add(10022)
+ ..add(10023)
+ ..add(10024)
+ ..add(10025)
+ ..add(10026)
+ ..add(10027)
+ ..add(10028)
+ ..add(10029)
+ ..add(10030)
+ ..add(10031)
+ ..add(10032)
+ ..add(10033)
+ ..add(10034)
+ ..add(10035)
+ ..add(10036)
+ ..add(10037)
+ ..add(10038)
+ ..add(10039)
+ ..add(10040)
+ ..add(10041)
+ ..add(10042)
+ ..add(10043)
+ ..add(10044)
+ ..add(10045)
+ ..add(10046)
+ ..add(10047)
+ ..add(10048)
+ ..add(10049)
+ ..add(10050)
+ ..add(10051)
+ ..add(10052)
+ ..add(10053)
+ ..add(10054)
+ ..add(10055)
+ ..add(10056)
+ ..add(10057)
+ ..add(10058)
+ ..add(10059)
+ ..add(10060)
+ ..add(10061)
+ ..add(10062)
+ ..add(10063)
+ ..add(10064)
+ ..add(10065)
+ ..add(10066)
+ ..add(10067)
+ ..add(10068)
+ ..add(10069)
+ ..add(10070)
+ ..add(10071)
+ ..add(10072)
+ ..add(10073)
+ ..add(10074)
+ ..add(10075)
+ ..add(10076)
+ ..add(10077)
+ ..add(10078)
+ ..add(10079)
+ ..add(10080)
+ ..add(10081)
+ ..add(10082)
+ ..add(10083)
+ ..add(10084)
+ ..add(10085)
+ ..add(10086)
+ ..add(10087)
+ ..add(10088)
+ ..add(10089)
+ ..add(10090)
+ ..add(10091)
+ ..add(10092)
+ ..add(10093)
+ ..add(10094)
+ ..add(10095)
+ ..add(10096)
+ ..add(10097)
+ ..add(10098)
+ ..add(10099)
+ ..add(10100)
+ ..add(10101)
+ ..add(10102)
+ ..add(10103)
+ ..add(10104)
+ ..add(10105)
+ ..add(10106)
+ ..add(10107)
+ ..add(10108)
+ ..add(10109)
+ ..add(10110)
+ ..add(10111)
+ ..add(10112)
+ ..add(10113)
+ ..add(10114)
+ ..add(10115)
+ ..add(10116)
+ ..add(10117)
+ ..add(10118)
+ ..add(10119)
+ ..add(10120)
+ ..add(10121)
+ ..add(10122)
+ ..add(10123)
+ ..add(10124)
+ ..add(10125)
+ ..add(10126)
+ ..add(10127)
+ ..add(10128)
+ ..add(10129)
+ ..add(10130)
+ ..add(10131)
+ ..add(10132)
+ ..add(10133)
+ ..add(10134)
+ ..add(10135)
+ ..add(10136)
+ ..add(10137)
+ ..add(10138)
+ ..add(10139)
+ ..add(10140)
+ ..add(10141)
+ ..add(10142)
+ ..add(10143)
+ ..add(10144)
+ ..add(10145)
+ ..add(10146)
+ ..add(10147)
+ ..add(10148)
+ ..add(10149)
+ ..add(10150)
+ ..add(10151)
+ ..add(10152)
+ ..add(10153)
+ ..add(10154)
+ ..add(10155)
+ ..add(10156)
+ ..add(10157)
+ ..add(10158)
+ ..add(10159)
+ ..add(10160)
+ ..add(10161)
+ ..add(10162)
+ ..add(10163)
+ ..add(10164)
+ ..add(10165)
+ ..add(10166)
+ ..add(10167)
+ ..add(10168)
+ ..add(10169)
+ ..add(10170)
+ ..add(10171)
+ ..add(10172)
+ ..add(10173)
+ ..add(10174)
+ ..add(10175)
+ ..add(10176)
+ ..add(10177)
+ ..add(10178)
+ ..add(10179)
+ ..add(10180)
+ ..add(10181)
+ ..add(10182)
+ ..add(10183)
+ ..add(10184)
+ ..add(10185)
+ ..add(10186)
+ ..add(10187)
+ ..add(10188)
+ ..add(10189)
+ ..add(10190)
+ ..add(10191)
+ ..add(10192)
+ ..add(10193)
+ ..add(10194)
+ ..add(10195)
+ ..add(10196)
+ ..add(10197)
+ ..add(10198)
+ ..add(10199)
+ ..add(10200)
+ ..add(10201)
+ ..add(10202)
+ ..add(10203)
+ ..add(10204)
+ ..add(10205)
+ ..add(10206)
+ ..add(10207)
+ ..add(10208)
+ ..add(10209)
+ ..add(10210)
+ ..add(10211)
+ ..add(10212)
+ ..add(10213)
+ ..add(10214)
+ ..add(10215)
+ ..add(10216)
+ ..add(10217)
+ ..add(10218)
+ ..add(10219)
+ ..add(10220)
+ ..add(10221)
+ ..add(10222)
+ ..add(10223)
+ ..add(10224)
+ ..add(10225)
+ ..add(10226)
+ ..add(10227)
+ ..add(10228)
+ ..add(10229)
+ ..add(10230)
+ ..add(10231)
+ ..add(10232)
+ ..add(10233)
+ ..add(10234)
+ ..add(10235)
+ ..add(10236)
+ ..add(10237)
+ ..add(10238)
+ ..add(10239)
+ ..add(10240)
+ ..add(10241)
+ ..add(10242)
+ ..add(10243)
+ ..add(10244)
+ ..add(10245)
+ ..add(10246)
+ ..add(10247)
+ ..add(10248)
+ ..add(10249)
+ ..add(10250)
+ ..add(10251)
+ ..add(10252)
+ ..add(10253)
+ ..add(10254)
+ ..add(10255)
+ ..add(10256)
+ ..add(10257)
+ ..add(10258)
+ ..add(10259)
+ ..add(10260)
+ ..add(10261)
+ ..add(10262)
+ ..add(10263)
+ ..add(10264)
+ ..add(10265)
+ ..add(10266)
+ ..add(10267)
+ ..add(10268)
+ ..add(10269)
+ ..add(10270)
+ ..add(10271)
+ ..add(10272)
+ ..add(10273)
+ ..add(10274)
+ ..add(10275)
+ ..add(10276)
+ ..add(10277)
+ ..add(10278)
+ ..add(10279)
+ ..add(10280)
+ ..add(10281)
+ ..add(10282)
+ ..add(10283)
+ ..add(10284)
+ ..add(10285)
+ ..add(10286)
+ ..add(10287)
+ ..add(10288)
+ ..add(10289)
+ ..add(10290)
+ ..add(10291)
+ ..add(10292)
+ ..add(10293)
+ ..add(10294)
+ ..add(10295)
+ ..add(10296)
+ ..add(10297)
+ ..add(10298)
+ ..add(10299)
+ ..add(10300)
+ ..add(10301)
+ ..add(10302)
+ ..add(10303)
+ ..add(10304)
+ ..add(10305)
+ ..add(10306)
+ ..add(10307)
+ ..add(10308)
+ ..add(10309)
+ ..add(10310)
+ ..add(10311)
+ ..add(10312)
+ ..add(10313)
+ ..add(10314)
+ ..add(10315)
+ ..add(10316)
+ ..add(10317)
+ ..add(10318)
+ ..add(10319)
+ ..add(10320)
+ ..add(10321)
+ ..add(10322)
+ ..add(10323)
+ ..add(10324)
+ ..add(10325)
+ ..add(10326)
+ ..add(10327)
+ ..add(10328)
+ ..add(10329)
+ ..add(10330)
+ ..add(10331)
+ ..add(10332)
+ ..add(10333)
+ ..add(10334)
+ ..add(10335)
+ ..add(10336)
+ ..add(10337)
+ ..add(10338)
+ ..add(10339)
+ ..add(10340)
+ ..add(10341)
+ ..add(10342)
+ ..add(10343)
+ ..add(10344)
+ ..add(10345)
+ ..add(10346)
+ ..add(10347)
+ ..add(10348)
+ ..add(10349)
+ ..add(10350)
+ ..add(10351)
+ ..add(10352)
+ ..add(10353)
+ ..add(10354)
+ ..add(10355)
+ ..add(10356)
+ ..add(10357)
+ ..add(10358)
+ ..add(10359)
+ ..add(10360)
+ ..add(10361)
+ ..add(10362)
+ ..add(10363)
+ ..add(10364)
+ ..add(10365)
+ ..add(10366)
+ ..add(10367)
+ ..add(10368)
+ ..add(10369)
+ ..add(10370)
+ ..add(10371)
+ ..add(10372)
+ ..add(10373)
+ ..add(10374)
+ ..add(10375)
+ ..add(10376)
+ ..add(10377)
+ ..add(10378)
+ ..add(10379)
+ ..add(10380)
+ ..add(10381)
+ ..add(10382)
+ ..add(10383)
+ ..add(10384)
+ ..add(10385)
+ ..add(10386)
+ ..add(10387)
+ ..add(10388)
+ ..add(10389)
+ ..add(10390)
+ ..add(10391)
+ ..add(10392)
+ ..add(10393)
+ ..add(10394)
+ ..add(10395)
+ ..add(10396)
+ ..add(10397)
+ ..add(10398)
+ ..add(10399)
+ ..add(10400)
+ ..add(10401)
+ ..add(10402)
+ ..add(10403)
+ ..add(10404)
+ ..add(10405)
+ ..add(10406)
+ ..add(10407)
+ ..add(10408)
+ ..add(10409)
+ ..add(10410)
+ ..add(10411)
+ ..add(10412)
+ ..add(10413)
+ ..add(10414)
+ ..add(10415)
+ ..add(10416)
+ ..add(10417)
+ ..add(10418)
+ ..add(10419)
+ ..add(10420)
+ ..add(10421)
+ ..add(10422)
+ ..add(10423)
+ ..add(10424)
+ ..add(10425)
+ ..add(10426)
+ ..add(10427)
+ ..add(10428)
+ ..add(10429)
+ ..add(10430)
+ ..add(10431)
+ ..add(10432)
+ ..add(10433)
+ ..add(10434)
+ ..add(10435)
+ ..add(10436)
+ ..add(10437)
+ ..add(10438)
+ ..add(10439)
+ ..add(10440)
+ ..add(10441)
+ ..add(10442)
+ ..add(10443)
+ ..add(10444)
+ ..add(10445)
+ ..add(10446)
+ ..add(10447)
+ ..add(10448)
+ ..add(10449)
+ ..add(10450)
+ ..add(10451)
+ ..add(10452)
+ ..add(10453)
+ ..add(10454)
+ ..add(10455)
+ ..add(10456)
+ ..add(10457)
+ ..add(10458)
+ ..add(10459)
+ ..add(10460)
+ ..add(10461)
+ ..add(10462)
+ ..add(10463)
+ ..add(10464)
+ ..add(10465)
+ ..add(10466)
+ ..add(10467)
+ ..add(10468)
+ ..add(10469)
+ ..add(10470)
+ ..add(10471)
+ ..add(10472)
+ ..add(10473)
+ ..add(10474)
+ ..add(10475)
+ ..add(10476)
+ ..add(10477)
+ ..add(10478)
+ ..add(10479)
+ ..add(10480)
+ ..add(10481)
+ ..add(10482)
+ ..add(10483)
+ ..add(10484)
+ ..add(10485)
+ ..add(10486)
+ ..add(10487)
+ ..add(10488)
+ ..add(10489)
+ ..add(10490)
+ ..add(10491)
+ ..add(10492)
+ ..add(10493)
+ ..add(10494)
+ ..add(10495)
+ ..add(10496)
+ ..add(10497)
+ ..add(10498)
+ ..add(10499)
+ ..add(10500)
+ ..add(10501)
+ ..add(10502)
+ ..add(10503)
+ ..add(10504)
+ ..add(10505)
+ ..add(10506)
+ ..add(10507)
+ ..add(10508)
+ ..add(10509)
+ ..add(10510)
+ ..add(10511)
+ ..add(10512)
+ ..add(10513)
+ ..add(10514)
+ ..add(10515)
+ ..add(10516)
+ ..add(10517)
+ ..add(10518)
+ ..add(10519)
+ ..add(10520)
+ ..add(10521)
+ ..add(10522)
+ ..add(10523)
+ ..add(10524)
+ ..add(10525)
+ ..add(10526)
+ ..add(10527)
+ ..add(10528)
+ ..add(10529)
+ ..add(10530)
+ ..add(10531)
+ ..add(10532)
+ ..add(10533)
+ ..add(10534)
+ ..add(10535)
+ ..add(10536)
+ ..add(10537)
+ ..add(10538)
+ ..add(10539)
+ ..add(10540)
+ ..add(10541)
+ ..add(10542)
+ ..add(10543)
+ ..add(10544)
+ ..add(10545)
+ ..add(10546)
+ ..add(10547)
+ ..add(10548)
+ ..add(10549)
+ ..add(10550)
+ ..add(10551)
+ ..add(10552)
+ ..add(10553)
+ ..add(10554)
+ ..add(10555)
+ ..add(10556)
+ ..add(10557)
+ ..add(10558)
+ ..add(10559)
+ ..add(10560)
+ ..add(10561)
+ ..add(10562)
+ ..add(10563)
+ ..add(10564)
+ ..add(10565)
+ ..add(10566)
+ ..add(10567)
+ ..add(10568)
+ ..add(10569)
+ ..add(10570)
+ ..add(10571)
+ ..add(10572)
+ ..add(10573)
+ ..add(10574)
+ ..add(10575)
+ ..add(10576)
+ ..add(10577)
+ ..add(10578)
+ ..add(10579)
+ ..add(10580)
+ ..add(10581)
+ ..add(10582)
+ ..add(10583)
+ ..add(10584)
+ ..add(10585)
+ ..add(10586)
+ ..add(10587)
+ ..add(10588)
+ ..add(10589)
+ ..add(10590)
+ ..add(10591)
+ ..add(10592)
+ ..add(10593)
+ ..add(10594)
+ ..add(10595)
+ ..add(10596)
+ ..add(10597)
+ ..add(10598)
+ ..add(10599)
+ ..add(10600)
+ ..add(10601)
+ ..add(10602)
+ ..add(10603)
+ ..add(10604)
+ ..add(10605)
+ ..add(10606)
+ ..add(10607)
+ ..add(10608)
+ ..add(10609)
+ ..add(10610)
+ ..add(10611)
+ ..add(10612)
+ ..add(10613)
+ ..add(10614)
+ ..add(10615)
+ ..add(10616)
+ ..add(10617)
+ ..add(10618)
+ ..add(10619)
+ ..add(10620)
+ ..add(10621)
+ ..add(10622)
+ ..add(10623)
+ ..add(10624)
+ ..add(10625)
+ ..add(10626)
+ ..add(10627)
+ ..add(10628)
+ ..add(10629)
+ ..add(10630)
+ ..add(10631)
+ ..add(10632)
+ ..add(10633)
+ ..add(10634)
+ ..add(10635)
+ ..add(10636)
+ ..add(10637)
+ ..add(10638)
+ ..add(10639)
+ ..add(10640)
+ ..add(10641)
+ ..add(10642)
+ ..add(10643)
+ ..add(10644)
+ ..add(10645)
+ ..add(10646)
+ ..add(10647)
+ ..add(10648)
+ ..add(10649)
+ ..add(10650)
+ ..add(10651)
+ ..add(10652)
+ ..add(10653)
+ ..add(10654)
+ ..add(10655)
+ ..add(10656)
+ ..add(10657)
+ ..add(10658)
+ ..add(10659)
+ ..add(10660)
+ ..add(10661)
+ ..add(10662)
+ ..add(10663)
+ ..add(10664)
+ ..add(10665)
+ ..add(10666)
+ ..add(10667)
+ ..add(10668)
+ ..add(10669)
+ ..add(10670)
+ ..add(10671)
+ ..add(10672)
+ ..add(10673)
+ ..add(10674)
+ ..add(10675)
+ ..add(10676)
+ ..add(10677)
+ ..add(10678)
+ ..add(10679)
+ ..add(10680)
+ ..add(10681)
+ ..add(10682)
+ ..add(10683)
+ ..add(10684)
+ ..add(10685)
+ ..add(10686)
+ ..add(10687)
+ ..add(10688)
+ ..add(10689)
+ ..add(10690)
+ ..add(10691)
+ ..add(10692)
+ ..add(10693)
+ ..add(10694)
+ ..add(10695)
+ ..add(10696)
+ ..add(10697)
+ ..add(10698)
+ ..add(10699)
+ ..add(10700)
+ ..add(10701)
+ ..add(10702)
+ ..add(10703)
+ ..add(10704)
+ ..add(10705)
+ ..add(10706)
+ ..add(10707)
+ ..add(10708)
+ ..add(10709)
+ ..add(10710)
+ ..add(10711)
+ ..add(10712)
+ ..add(10713)
+ ..add(10714)
+ ..add(10715)
+ ..add(10716)
+ ..add(10717)
+ ..add(10718)
+ ..add(10719)
+ ..add(10720)
+ ..add(10721)
+ ..add(10722)
+ ..add(10723)
+ ..add(10724)
+ ..add(10725)
+ ..add(10726)
+ ..add(10727)
+ ..add(10728)
+ ..add(10729)
+ ..add(10730)
+ ..add(10731)
+ ..add(10732)
+ ..add(10733)
+ ..add(10734)
+ ..add(10735)
+ ..add(10736)
+ ..add(10737)
+ ..add(10738)
+ ..add(10739)
+ ..add(10740)
+ ..add(10741)
+ ..add(10742)
+ ..add(10743)
+ ..add(10744)
+ ..add(10745)
+ ..add(10746)
+ ..add(10747)
+ ..add(10748)
+ ..add(10749)
+ ..add(10750)
+ ..add(10751)
+ ..add(10752)
+ ..add(10753)
+ ..add(10754)
+ ..add(10755)
+ ..add(10756)
+ ..add(10757)
+ ..add(10758)
+ ..add(10759)
+ ..add(10760)
+ ..add(10761)
+ ..add(10762)
+ ..add(10763)
+ ..add(10764)
+ ..add(10765)
+ ..add(10766)
+ ..add(10767)
+ ..add(10768)
+ ..add(10769)
+ ..add(10770)
+ ..add(10771)
+ ..add(10772)
+ ..add(10773)
+ ..add(10774)
+ ..add(10775)
+ ..add(10776)
+ ..add(10777)
+ ..add(10778)
+ ..add(10779)
+ ..add(10780)
+ ..add(10781)
+ ..add(10782)
+ ..add(10783)
+ ..add(10784)
+ ..add(10785)
+ ..add(10786)
+ ..add(10787)
+ ..add(10788)
+ ..add(10789)
+ ..add(10790)
+ ..add(10791)
+ ..add(10792)
+ ..add(10793)
+ ..add(10794)
+ ..add(10795)
+ ..add(10796)
+ ..add(10797)
+ ..add(10798)
+ ..add(10799)
+ ..add(10800)
+ ..add(10801)
+ ..add(10802)
+ ..add(10803)
+ ..add(10804)
+ ..add(10805)
+ ..add(10806)
+ ..add(10807)
+ ..add(10808)
+ ..add(10809)
+ ..add(10810)
+ ..add(10811)
+ ..add(10812)
+ ..add(10813)
+ ..add(10814)
+ ..add(10815)
+ ..add(10816)
+ ..add(10817)
+ ..add(10818)
+ ..add(10819)
+ ..add(10820)
+ ..add(10821)
+ ..add(10822)
+ ..add(10823)
+ ..add(10824)
+ ..add(10825)
+ ..add(10826)
+ ..add(10827)
+ ..add(10828)
+ ..add(10829)
+ ..add(10830)
+ ..add(10831)
+ ..add(10832)
+ ..add(10833)
+ ..add(10834)
+ ..add(10835)
+ ..add(10836)
+ ..add(10837)
+ ..add(10838)
+ ..add(10839)
+ ..add(10840)
+ ..add(10841)
+ ..add(10842)
+ ..add(10843)
+ ..add(10844)
+ ..add(10845)
+ ..add(10846)
+ ..add(10847)
+ ..add(10848)
+ ..add(10849)
+ ..add(10850)
+ ..add(10851)
+ ..add(10852)
+ ..add(10853)
+ ..add(10854)
+ ..add(10855)
+ ..add(10856)
+ ..add(10857)
+ ..add(10858)
+ ..add(10859)
+ ..add(10860)
+ ..add(10861)
+ ..add(10862)
+ ..add(10863)
+ ..add(10864)
+ ..add(10865)
+ ..add(10866)
+ ..add(10867)
+ ..add(10868)
+ ..add(10869)
+ ..add(10870)
+ ..add(10871)
+ ..add(10872)
+ ..add(10873)
+ ..add(10874)
+ ..add(10875)
+ ..add(10876)
+ ..add(10877)
+ ..add(10878)
+ ..add(10879)
+ ..add(10880)
+ ..add(10881)
+ ..add(10882)
+ ..add(10883)
+ ..add(10884)
+ ..add(10885)
+ ..add(10886)
+ ..add(10887)
+ ..add(10888)
+ ..add(10889)
+ ..add(10890)
+ ..add(10891)
+ ..add(10892)
+ ..add(10893)
+ ..add(10894)
+ ..add(10895)
+ ..add(10896)
+ ..add(10897)
+ ..add(10898)
+ ..add(10899)
+ ..add(10900)
+ ..add(10901)
+ ..add(10902)
+ ..add(10903)
+ ..add(10904)
+ ..add(10905)
+ ..add(10906)
+ ..add(10907)
+ ..add(10908)
+ ..add(10909)
+ ..add(10910)
+ ..add(10911)
+ ..add(10912)
+ ..add(10913)
+ ..add(10914)
+ ..add(10915)
+ ..add(10916)
+ ..add(10917)
+ ..add(10918)
+ ..add(10919)
+ ..add(10920)
+ ..add(10921)
+ ..add(10922)
+ ..add(10923)
+ ..add(10924)
+ ..add(10925)
+ ..add(10926)
+ ..add(10927)
+ ..add(10928)
+ ..add(10929)
+ ..add(10930)
+ ..add(10931)
+ ..add(10932)
+ ..add(10933)
+ ..add(10934)
+ ..add(10935)
+ ..add(10936)
+ ..add(10937)
+ ..add(10938)
+ ..add(10939)
+ ..add(10940)
+ ..add(10941)
+ ..add(10942)
+ ..add(10943)
+ ..add(10944)
+ ..add(10945)
+ ..add(10946)
+ ..add(10947)
+ ..add(10948)
+ ..add(10949)
+ ..add(10950)
+ ..add(10951)
+ ..add(10952)
+ ..add(10953)
+ ..add(10954)
+ ..add(10955)
+ ..add(10956)
+ ..add(10957)
+ ..add(10958)
+ ..add(10959)
+ ..add(10960)
+ ..add(10961)
+ ..add(10962)
+ ..add(10963)
+ ..add(10964)
+ ..add(10965)
+ ..add(10966)
+ ..add(10967)
+ ..add(10968)
+ ..add(10969)
+ ..add(10970)
+ ..add(10971)
+ ..add(10972)
+ ..add(10973)
+ ..add(10974)
+ ..add(10975)
+ ..add(10976)
+ ..add(10977)
+ ..add(10978)
+ ..add(10979)
+ ..add(10980)
+ ..add(10981)
+ ..add(10982)
+ ..add(10983)
+ ..add(10984)
+ ..add(10985)
+ ..add(10986)
+ ..add(10987)
+ ..add(10988)
+ ..add(10989)
+ ..add(10990)
+ ..add(10991)
+ ..add(10992)
+ ..add(10993)
+ ..add(10994)
+ ..add(10995)
+ ..add(10996)
+ ..add(10997)
+ ..add(10998)
+ ..add(10999)
+ ..add(11000)
+ ..add(11001)
+ ..add(11002)
+ ..add(11003)
+ ..add(11004)
+ ..add(11005)
+ ..add(11006)
+ ..add(11007)
+ ..add(11008)
+ ..add(11009)
+ ..add(11010)
+ ..add(11011)
+ ..add(11012)
+ ..add(11013)
+ ..add(11014)
+ ..add(11015)
+ ..add(11016)
+ ..add(11017)
+ ..add(11018)
+ ..add(11019)
+ ..add(11020)
+ ..add(11021)
+ ..add(11022)
+ ..add(11023)
+ ..add(11024)
+ ..add(11025)
+ ..add(11026)
+ ..add(11027)
+ ..add(11028)
+ ..add(11029)
+ ..add(11030)
+ ..add(11031)
+ ..add(11032)
+ ..add(11033)
+ ..add(11034)
+ ..add(11035)
+ ..add(11036)
+ ..add(11037)
+ ..add(11038)
+ ..add(11039)
+ ..add(11040)
+ ..add(11041)
+ ..add(11042)
+ ..add(11043)
+ ..add(11044)
+ ..add(11045)
+ ..add(11046)
+ ..add(11047)
+ ..add(11048)
+ ..add(11049)
+ ..add(11050)
+ ..add(11051)
+ ..add(11052)
+ ..add(11053)
+ ..add(11054)
+ ..add(11055)
+ ..add(11056)
+ ..add(11057)
+ ..add(11058)
+ ..add(11059)
+ ..add(11060)
+ ..add(11061)
+ ..add(11062)
+ ..add(11063)
+ ..add(11064)
+ ..add(11065)
+ ..add(11066)
+ ..add(11067)
+ ..add(11068)
+ ..add(11069)
+ ..add(11070)
+ ..add(11071)
+ ..add(11072)
+ ..add(11073)
+ ..add(11074)
+ ..add(11075)
+ ..add(11076)
+ ..add(11077)
+ ..add(11078)
+ ..add(11079)
+ ..add(11080)
+ ..add(11081)
+ ..add(11082)
+ ..add(11083)
+ ..add(11084)
+ ..add(11085)
+ ..add(11086)
+ ..add(11087)
+ ..add(11088)
+ ..add(11089)
+ ..add(11090)
+ ..add(11091)
+ ..add(11092)
+ ..add(11093)
+ ..add(11094)
+ ..add(11095)
+ ..add(11096)
+ ..add(11097)
+ ..add(11098)
+ ..add(11099)
+ ..add(11100)
+ ..add(11101)
+ ..add(11102)
+ ..add(11103)
+ ..add(11104)
+ ..add(11105)
+ ..add(11106)
+ ..add(11107)
+ ..add(11108)
+ ..add(11109)
+ ..add(11110)
+ ..add(11111)
+ ..add(11112)
+ ..add(11113)
+ ..add(11114)
+ ..add(11115)
+ ..add(11116)
+ ..add(11117)
+ ..add(11118)
+ ..add(11119)
+ ..add(11120)
+ ..add(11121)
+ ..add(11122)
+ ..add(11123)
+ ..add(11124)
+ ..add(11125)
+ ..add(11126)
+ ..add(11127)
+ ..add(11128)
+ ..add(11129)
+ ..add(11130)
+ ..add(11131)
+ ..add(11132)
+ ..add(11133)
+ ..add(11134)
+ ..add(11135)
+ ..add(11136)
+ ..add(11137)
+ ..add(11138)
+ ..add(11139)
+ ..add(11140)
+ ..add(11141)
+ ..add(11142)
+ ..add(11143)
+ ..add(11144)
+ ..add(11145)
+ ..add(11146)
+ ..add(11147)
+ ..add(11148)
+ ..add(11149)
+ ..add(11150)
+ ..add(11151)
+ ..add(11152)
+ ..add(11153)
+ ..add(11154)
+ ..add(11155)
+ ..add(11156)
+ ..add(11157)
+ ..add(11158)
+ ..add(11159)
+ ..add(11160)
+ ..add(11161)
+ ..add(11162)
+ ..add(11163)
+ ..add(11164)
+ ..add(11165)
+ ..add(11166)
+ ..add(11167)
+ ..add(11168)
+ ..add(11169)
+ ..add(11170)
+ ..add(11171)
+ ..add(11172)
+ ..add(11173)
+ ..add(11174)
+ ..add(11175)
+ ..add(11176)
+ ..add(11177)
+ ..add(11178)
+ ..add(11179)
+ ..add(11180)
+ ..add(11181)
+ ..add(11182)
+ ..add(11183)
+ ..add(11184)
+ ..add(11185)
+ ..add(11186)
+ ..add(11187)
+ ..add(11188)
+ ..add(11189)
+ ..add(11190)
+ ..add(11191)
+ ..add(11192)
+ ..add(11193)
+ ..add(11194)
+ ..add(11195)
+ ..add(11196)
+ ..add(11197)
+ ..add(11198)
+ ..add(11199)
+ ..add(11200)
+ ..add(11201)
+ ..add(11202)
+ ..add(11203)
+ ..add(11204)
+ ..add(11205)
+ ..add(11206)
+ ..add(11207)
+ ..add(11208)
+ ..add(11209)
+ ..add(11210)
+ ..add(11211)
+ ..add(11212)
+ ..add(11213)
+ ..add(11214)
+ ..add(11215)
+ ..add(11216)
+ ..add(11217)
+ ..add(11218)
+ ..add(11219)
+ ..add(11220)
+ ..add(11221)
+ ..add(11222)
+ ..add(11223)
+ ..add(11224)
+ ..add(11225)
+ ..add(11226)
+ ..add(11227)
+ ..add(11228)
+ ..add(11229)
+ ..add(11230)
+ ..add(11231)
+ ..add(11232)
+ ..add(11233)
+ ..add(11234)
+ ..add(11235)
+ ..add(11236)
+ ..add(11237)
+ ..add(11238)
+ ..add(11239)
+ ..add(11240)
+ ..add(11241)
+ ..add(11242)
+ ..add(11243)
+ ..add(11244)
+ ..add(11245)
+ ..add(11246)
+ ..add(11247)
+ ..add(11248)
+ ..add(11249)
+ ..add(11250)
+ ..add(11251)
+ ..add(11252)
+ ..add(11253)
+ ..add(11254)
+ ..add(11255)
+ ..add(11256)
+ ..add(11257)
+ ..add(11258)
+ ..add(11259)
+ ..add(11260)
+ ..add(11261)
+ ..add(11262)
+ ..add(11263)
+ ..add(11264)
+ ..add(11265)
+ ..add(11266)
+ ..add(11267)
+ ..add(11268)
+ ..add(11269)
+ ..add(11270)
+ ..add(11271)
+ ..add(11272)
+ ..add(11273)
+ ..add(11274)
+ ..add(11275)
+ ..add(11276)
+ ..add(11277)
+ ..add(11278)
+ ..add(11279)
+ ..add(11280)
+ ..add(11281)
+ ..add(11282)
+ ..add(11283)
+ ..add(11284)
+ ..add(11285)
+ ..add(11286)
+ ..add(11287)
+ ..add(11288)
+ ..add(11289)
+ ..add(11290)
+ ..add(11291)
+ ..add(11292)
+ ..add(11293)
+ ..add(11294)
+ ..add(11295)
+ ..add(11296)
+ ..add(11297)
+ ..add(11298)
+ ..add(11299)
+ ..add(11300)
+ ..add(11301)
+ ..add(11302)
+ ..add(11303)
+ ..add(11304)
+ ..add(11305)
+ ..add(11306)
+ ..add(11307)
+ ..add(11308)
+ ..add(11309)
+ ..add(11310)
+ ..add(11311)
+ ..add(11312)
+ ..add(11313)
+ ..add(11314)
+ ..add(11315)
+ ..add(11316)
+ ..add(11317)
+ ..add(11318)
+ ..add(11319)
+ ..add(11320)
+ ..add(11321)
+ ..add(11322)
+ ..add(11323)
+ ..add(11324)
+ ..add(11325)
+ ..add(11326)
+ ..add(11327)
+ ..add(11328)
+ ..add(11329)
+ ..add(11330)
+ ..add(11331)
+ ..add(11332)
+ ..add(11333)
+ ..add(11334)
+ ..add(11335)
+ ..add(11336)
+ ..add(11337)
+ ..add(11338)
+ ..add(11339)
+ ..add(11340)
+ ..add(11341)
+ ..add(11342)
+ ..add(11343)
+ ..add(11344)
+ ..add(11345)
+ ..add(11346)
+ ..add(11347)
+ ..add(11348)
+ ..add(11349)
+ ..add(11350)
+ ..add(11351)
+ ..add(11352)
+ ..add(11353)
+ ..add(11354)
+ ..add(11355)
+ ..add(11356)
+ ..add(11357)
+ ..add(11358)
+ ..add(11359)
+ ..add(11360)
+ ..add(11361)
+ ..add(11362)
+ ..add(11363)
+ ..add(11364)
+ ..add(11365)
+ ..add(11366)
+ ..add(11367)
+ ..add(11368)
+ ..add(11369)
+ ..add(11370)
+ ..add(11371)
+ ..add(11372)
+ ..add(11373)
+ ..add(11374)
+ ..add(11375)
+ ..add(11376)
+ ..add(11377)
+ ..add(11378)
+ ..add(11379)
+ ..add(11380)
+ ..add(11381)
+ ..add(11382)
+ ..add(11383)
+ ..add(11384)
+ ..add(11385)
+ ..add(11386)
+ ..add(11387)
+ ..add(11388)
+ ..add(11389)
+ ..add(11390)
+ ..add(11391)
+ ..add(11392)
+ ..add(11393)
+ ..add(11394)
+ ..add(11395)
+ ..add(11396)
+ ..add(11397)
+ ..add(11398)
+ ..add(11399)
+ ..add(11400)
+ ..add(11401)
+ ..add(11402)
+ ..add(11403)
+ ..add(11404)
+ ..add(11405)
+ ..add(11406)
+ ..add(11407)
+ ..add(11408)
+ ..add(11409)
+ ..add(11410)
+ ..add(11411)
+ ..add(11412)
+ ..add(11413)
+ ..add(11414)
+ ..add(11415)
+ ..add(11416)
+ ..add(11417)
+ ..add(11418)
+ ..add(11419)
+ ..add(11420)
+ ..add(11421)
+ ..add(11422)
+ ..add(11423)
+ ..add(11424)
+ ..add(11425)
+ ..add(11426)
+ ..add(11427)
+ ..add(11428)
+ ..add(11429)
+ ..add(11430)
+ ..add(11431)
+ ..add(11432)
+ ..add(11433)
+ ..add(11434)
+ ..add(11435)
+ ..add(11436)
+ ..add(11437)
+ ..add(11438)
+ ..add(11439)
+ ..add(11440)
+ ..add(11441)
+ ..add(11442)
+ ..add(11443)
+ ..add(11444)
+ ..add(11445)
+ ..add(11446)
+ ..add(11447)
+ ..add(11448)
+ ..add(11449)
+ ..add(11450)
+ ..add(11451)
+ ..add(11452)
+ ..add(11453)
+ ..add(11454)
+ ..add(11455)
+ ..add(11456)
+ ..add(11457)
+ ..add(11458)
+ ..add(11459)
+ ..add(11460)
+ ..add(11461)
+ ..add(11462)
+ ..add(11463)
+ ..add(11464)
+ ..add(11465)
+ ..add(11466)
+ ..add(11467)
+ ..add(11468)
+ ..add(11469)
+ ..add(11470)
+ ..add(11471)
+ ..add(11472)
+ ..add(11473)
+ ..add(11474)
+ ..add(11475)
+ ..add(11476)
+ ..add(11477)
+ ..add(11478)
+ ..add(11479)
+ ..add(11480)
+ ..add(11481)
+ ..add(11482)
+ ..add(11483)
+ ..add(11484)
+ ..add(11485)
+ ..add(11486)
+ ..add(11487)
+ ..add(11488)
+ ..add(11489)
+ ..add(11490)
+ ..add(11491)
+ ..add(11492)
+ ..add(11493)
+ ..add(11494)
+ ..add(11495)
+ ..add(11496)
+ ..add(11497)
+ ..add(11498)
+ ..add(11499)
+ ..add(11500)
+ ..add(11501)
+ ..add(11502)
+ ..add(11503)
+ ..add(11504)
+ ..add(11505)
+ ..add(11506)
+ ..add(11507)
+ ..add(11508)
+ ..add(11509)
+ ..add(11510)
+ ..add(11511)
+ ..add(11512)
+ ..add(11513)
+ ..add(11514)
+ ..add(11515)
+ ..add(11516)
+ ..add(11517)
+ ..add(11518)
+ ..add(11519)
+ ..add(11520)
+ ..add(11521)
+ ..add(11522)
+ ..add(11523)
+ ..add(11524)
+ ..add(11525)
+ ..add(11526)
+ ..add(11527)
+ ..add(11528)
+ ..add(11529)
+ ..add(11530)
+ ..add(11531)
+ ..add(11532)
+ ..add(11533)
+ ..add(11534)
+ ..add(11535)
+ ..add(11536)
+ ..add(11537)
+ ..add(11538)
+ ..add(11539)
+ ..add(11540)
+ ..add(11541)
+ ..add(11542)
+ ..add(11543)
+ ..add(11544)
+ ..add(11545)
+ ..add(11546)
+ ..add(11547)
+ ..add(11548)
+ ..add(11549)
+ ..add(11550)
+ ..add(11551)
+ ..add(11552)
+ ..add(11553)
+ ..add(11554)
+ ..add(11555)
+ ..add(11556)
+ ..add(11557)
+ ..add(11558)
+ ..add(11559)
+ ..add(11560)
+ ..add(11561)
+ ..add(11562)
+ ..add(11563)
+ ..add(11564)
+ ..add(11565)
+ ..add(11566)
+ ..add(11567)
+ ..add(11568)
+ ..add(11569)
+ ..add(11570)
+ ..add(11571)
+ ..add(11572)
+ ..add(11573)
+ ..add(11574)
+ ..add(11575)
+ ..add(11576)
+ ..add(11577)
+ ..add(11578)
+ ..add(11579)
+ ..add(11580)
+ ..add(11581)
+ ..add(11582)
+ ..add(11583)
+ ..add(11584)
+ ..add(11585)
+ ..add(11586)
+ ..add(11587)
+ ..add(11588)
+ ..add(11589)
+ ..add(11590)
+ ..add(11591)
+ ..add(11592)
+ ..add(11593)
+ ..add(11594)
+ ..add(11595)
+ ..add(11596)
+ ..add(11597)
+ ..add(11598)
+ ..add(11599)
+ ..add(11600)
+ ..add(11601)
+ ..add(11602)
+ ..add(11603)
+ ..add(11604)
+ ..add(11605)
+ ..add(11606)
+ ..add(11607)
+ ..add(11608)
+ ..add(11609)
+ ..add(11610)
+ ..add(11611)
+ ..add(11612)
+ ..add(11613)
+ ..add(11614)
+ ..add(11615)
+ ..add(11616)
+ ..add(11617)
+ ..add(11618)
+ ..add(11619)
+ ..add(11620)
+ ..add(11621)
+ ..add(11622)
+ ..add(11623)
+ ..add(11624)
+ ..add(11625)
+ ..add(11626)
+ ..add(11627)
+ ..add(11628)
+ ..add(11629)
+ ..add(11630)
+ ..add(11631)
+ ..add(11632)
+ ..add(11633)
+ ..add(11634)
+ ..add(11635)
+ ..add(11636)
+ ..add(11637)
+ ..add(11638)
+ ..add(11639)
+ ..add(11640)
+ ..add(11641)
+ ..add(11642)
+ ..add(11643)
+ ..add(11644)
+ ..add(11645)
+ ..add(11646)
+ ..add(11647)
+ ..add(11648)
+ ..add(11649)
+ ..add(11650)
+ ..add(11651)
+ ..add(11652)
+ ..add(11653)
+ ..add(11654)
+ ..add(11655)
+ ..add(11656)
+ ..add(11657)
+ ..add(11658)
+ ..add(11659)
+ ..add(11660)
+ ..add(11661)
+ ..add(11662)
+ ..add(11663)
+ ..add(11664)
+ ..add(11665)
+ ..add(11666)
+ ..add(11667)
+ ..add(11668)
+ ..add(11669)
+ ..add(11670)
+ ..add(11671)
+ ..add(11672)
+ ..add(11673)
+ ..add(11674)
+ ..add(11675)
+ ..add(11676)
+ ..add(11677)
+ ..add(11678)
+ ..add(11679)
+ ..add(11680)
+ ..add(11681)
+ ..add(11682)
+ ..add(11683)
+ ..add(11684)
+ ..add(11685)
+ ..add(11686)
+ ..add(11687)
+ ..add(11688)
+ ..add(11689)
+ ..add(11690)
+ ..add(11691)
+ ..add(11692)
+ ..add(11693)
+ ..add(11694)
+ ..add(11695)
+ ..add(11696)
+ ..add(11697)
+ ..add(11698)
+ ..add(11699)
+ ..add(11700)
+ ..add(11701)
+ ..add(11702)
+ ..add(11703)
+ ..add(11704)
+ ..add(11705)
+ ..add(11706)
+ ..add(11707)
+ ..add(11708)
+ ..add(11709)
+ ..add(11710)
+ ..add(11711)
+ ..add(11712)
+ ..add(11713)
+ ..add(11714)
+ ..add(11715)
+ ..add(11716)
+ ..add(11717)
+ ..add(11718)
+ ..add(11719)
+ ..add(11720)
+ ..add(11721)
+ ..add(11722)
+ ..add(11723)
+ ..add(11724)
+ ..add(11725)
+ ..add(11726)
+ ..add(11727)
+ ..add(11728)
+ ..add(11729)
+ ..add(11730)
+ ..add(11731)
+ ..add(11732)
+ ..add(11733)
+ ..add(11734)
+ ..add(11735)
+ ..add(11736)
+ ..add(11737)
+ ..add(11738)
+ ..add(11739)
+ ..add(11740)
+ ..add(11741)
+ ..add(11742)
+ ..add(11743)
+ ..add(11744)
+ ..add(11745)
+ ..add(11746)
+ ..add(11747)
+ ..add(11748)
+ ..add(11749)
+ ..add(11750)
+ ..add(11751)
+ ..add(11752)
+ ..add(11753)
+ ..add(11754)
+ ..add(11755)
+ ..add(11756)
+ ..add(11757)
+ ..add(11758)
+ ..add(11759)
+ ..add(11760)
+ ..add(11761)
+ ..add(11762)
+ ..add(11763)
+ ..add(11764)
+ ..add(11765)
+ ..add(11766)
+ ..add(11767)
+ ..add(11768)
+ ..add(11769)
+ ..add(11770)
+ ..add(11771)
+ ..add(11772)
+ ..add(11773)
+ ..add(11774)
+ ..add(11775)
+ ..add(11776)
+ ..add(11777)
+ ..add(11778)
+ ..add(11779)
+ ..add(11780)
+ ..add(11781)
+ ..add(11782)
+ ..add(11783)
+ ..add(11784)
+ ..add(11785)
+ ..add(11786)
+ ..add(11787)
+ ..add(11788)
+ ..add(11789)
+ ..add(11790)
+ ..add(11791)
+ ..add(11792)
+ ..add(11793)
+ ..add(11794)
+ ..add(11795)
+ ..add(11796)
+ ..add(11797)
+ ..add(11798)
+ ..add(11799)
+ ..add(11800)
+ ..add(11801)
+ ..add(11802)
+ ..add(11803)
+ ..add(11804)
+ ..add(11805)
+ ..add(11806)
+ ..add(11807)
+ ..add(11808)
+ ..add(11809)
+ ..add(11810)
+ ..add(11811)
+ ..add(11812)
+ ..add(11813)
+ ..add(11814)
+ ..add(11815)
+ ..add(11816)
+ ..add(11817)
+ ..add(11818)
+ ..add(11819)
+ ..add(11820)
+ ..add(11821)
+ ..add(11822)
+ ..add(11823)
+ ..add(11824)
+ ..add(11825)
+ ..add(11826)
+ ..add(11827)
+ ..add(11828)
+ ..add(11829)
+ ..add(11830)
+ ..add(11831)
+ ..add(11832)
+ ..add(11833)
+ ..add(11834)
+ ..add(11835)
+ ..add(11836)
+ ..add(11837)
+ ..add(11838)
+ ..add(11839)
+ ..add(11840)
+ ..add(11841)
+ ..add(11842)
+ ..add(11843)
+ ..add(11844)
+ ..add(11845)
+ ..add(11846)
+ ..add(11847)
+ ..add(11848)
+ ..add(11849)
+ ..add(11850)
+ ..add(11851)
+ ..add(11852)
+ ..add(11853)
+ ..add(11854)
+ ..add(11855)
+ ..add(11856)
+ ..add(11857)
+ ..add(11858)
+ ..add(11859)
+ ..add(11860)
+ ..add(11861)
+ ..add(11862)
+ ..add(11863)
+ ..add(11864)
+ ..add(11865)
+ ..add(11866)
+ ..add(11867)
+ ..add(11868)
+ ..add(11869)
+ ..add(11870)
+ ..add(11871)
+ ..add(11872)
+ ..add(11873)
+ ..add(11874)
+ ..add(11875)
+ ..add(11876)
+ ..add(11877)
+ ..add(11878)
+ ..add(11879)
+ ..add(11880)
+ ..add(11881)
+ ..add(11882)
+ ..add(11883)
+ ..add(11884)
+ ..add(11885)
+ ..add(11886)
+ ..add(11887)
+ ..add(11888)
+ ..add(11889)
+ ..add(11890)
+ ..add(11891)
+ ..add(11892)
+ ..add(11893)
+ ..add(11894)
+ ..add(11895)
+ ..add(11896)
+ ..add(11897)
+ ..add(11898)
+ ..add(11899)
+ ..add(11900)
+ ..add(11901)
+ ..add(11902)
+ ..add(11903)
+ ..add(11904)
+ ..add(11905)
+ ..add(11906)
+ ..add(11907)
+ ..add(11908)
+ ..add(11909)
+ ..add(11910)
+ ..add(11911)
+ ..add(11912)
+ ..add(11913)
+ ..add(11914)
+ ..add(11915)
+ ..add(11916)
+ ..add(11917)
+ ..add(11918)
+ ..add(11919)
+ ..add(11920)
+ ..add(11921)
+ ..add(11922)
+ ..add(11923)
+ ..add(11924)
+ ..add(11925)
+ ..add(11926)
+ ..add(11927)
+ ..add(11928)
+ ..add(11929)
+ ..add(11930)
+ ..add(11931)
+ ..add(11932)
+ ..add(11933)
+ ..add(11934)
+ ..add(11935)
+ ..add(11936)
+ ..add(11937)
+ ..add(11938)
+ ..add(11939)
+ ..add(11940)
+ ..add(11941)
+ ..add(11942)
+ ..add(11943)
+ ..add(11944)
+ ..add(11945)
+ ..add(11946)
+ ..add(11947)
+ ..add(11948)
+ ..add(11949)
+ ..add(11950)
+ ..add(11951)
+ ..add(11952)
+ ..add(11953)
+ ..add(11954)
+ ..add(11955)
+ ..add(11956)
+ ..add(11957)
+ ..add(11958)
+ ..add(11959)
+ ..add(11960)
+ ..add(11961)
+ ..add(11962)
+ ..add(11963)
+ ..add(11964)
+ ..add(11965)
+ ..add(11966)
+ ..add(11967)
+ ..add(11968)
+ ..add(11969)
+ ..add(11970)
+ ..add(11971)
+ ..add(11972)
+ ..add(11973)
+ ..add(11974)
+ ..add(11975)
+ ..add(11976)
+ ..add(11977)
+ ..add(11978)
+ ..add(11979)
+ ..add(11980)
+ ..add(11981)
+ ..add(11982)
+ ..add(11983)
+ ..add(11984)
+ ..add(11985)
+ ..add(11986)
+ ..add(11987)
+ ..add(11988)
+ ..add(11989)
+ ..add(11990)
+ ..add(11991)
+ ..add(11992)
+ ..add(11993)
+ ..add(11994)
+ ..add(11995)
+ ..add(11996)
+ ..add(11997)
+ ..add(11998)
+ ..add(11999)
+ ..add(12000)
+ ..add(12001)
+ ..add(12002)
+ ..add(12003)
+ ..add(12004)
+ ..add(12005)
+ ..add(12006)
+ ..add(12007)
+ ..add(12008)
+ ..add(12009)
+ ..add(12010)
+ ..add(12011)
+ ..add(12012)
+ ..add(12013)
+ ..add(12014)
+ ..add(12015)
+ ..add(12016)
+ ..add(12017)
+ ..add(12018)
+ ..add(12019)
+ ..add(12020)
+ ..add(12021)
+ ..add(12022)
+ ..add(12023)
+ ..add(12024)
+ ..add(12025)
+ ..add(12026)
+ ..add(12027)
+ ..add(12028)
+ ..add(12029)
+ ..add(12030)
+ ..add(12031)
+ ..add(12032)
+ ..add(12033)
+ ..add(12034)
+ ..add(12035)
+ ..add(12036)
+ ..add(12037)
+ ..add(12038)
+ ..add(12039)
+ ..add(12040)
+ ..add(12041)
+ ..add(12042)
+ ..add(12043)
+ ..add(12044)
+ ..add(12045)
+ ..add(12046)
+ ..add(12047)
+ ..add(12048)
+ ..add(12049)
+ ..add(12050)
+ ..add(12051)
+ ..add(12052)
+ ..add(12053)
+ ..add(12054)
+ ..add(12055)
+ ..add(12056)
+ ..add(12057)
+ ..add(12058)
+ ..add(12059)
+ ..add(12060)
+ ..add(12061)
+ ..add(12062)
+ ..add(12063)
+ ..add(12064)
+ ..add(12065)
+ ..add(12066)
+ ..add(12067)
+ ..add(12068)
+ ..add(12069)
+ ..add(12070)
+ ..add(12071)
+ ..add(12072)
+ ..add(12073)
+ ..add(12074)
+ ..add(12075)
+ ..add(12076)
+ ..add(12077)
+ ..add(12078)
+ ..add(12079)
+ ..add(12080)
+ ..add(12081)
+ ..add(12082)
+ ..add(12083)
+ ..add(12084)
+ ..add(12085)
+ ..add(12086)
+ ..add(12087)
+ ..add(12088)
+ ..add(12089)
+ ..add(12090)
+ ..add(12091)
+ ..add(12092)
+ ..add(12093)
+ ..add(12094)
+ ..add(12095)
+ ..add(12096)
+ ..add(12097)
+ ..add(12098)
+ ..add(12099)
+ ..add(12100)
+ ..add(12101)
+ ..add(12102)
+ ..add(12103)
+ ..add(12104)
+ ..add(12105)
+ ..add(12106)
+ ..add(12107)
+ ..add(12108)
+ ..add(12109)
+ ..add(12110)
+ ..add(12111)
+ ..add(12112)
+ ..add(12113)
+ ..add(12114)
+ ..add(12115)
+ ..add(12116)
+ ..add(12117)
+ ..add(12118)
+ ..add(12119)
+ ..add(12120)
+ ..add(12121)
+ ..add(12122)
+ ..add(12123)
+ ..add(12124)
+ ..add(12125)
+ ..add(12126)
+ ..add(12127)
+ ..add(12128)
+ ..add(12129)
+ ..add(12130)
+ ..add(12131)
+ ..add(12132)
+ ..add(12133)
+ ..add(12134)
+ ..add(12135)
+ ..add(12136)
+ ..add(12137)
+ ..add(12138)
+ ..add(12139)
+ ..add(12140)
+ ..add(12141)
+ ..add(12142)
+ ..add(12143)
+ ..add(12144)
+ ..add(12145)
+ ..add(12146)
+ ..add(12147)
+ ..add(12148)
+ ..add(12149)
+ ..add(12150)
+ ..add(12151)
+ ..add(12152)
+ ..add(12153)
+ ..add(12154)
+ ..add(12155)
+ ..add(12156)
+ ..add(12157)
+ ..add(12158)
+ ..add(12159)
+ ..add(12160)
+ ..add(12161)
+ ..add(12162)
+ ..add(12163)
+ ..add(12164)
+ ..add(12165)
+ ..add(12166)
+ ..add(12167)
+ ..add(12168)
+ ..add(12169)
+ ..add(12170)
+ ..add(12171)
+ ..add(12172)
+ ..add(12173)
+ ..add(12174)
+ ..add(12175)
+ ..add(12176)
+ ..add(12177)
+ ..add(12178)
+ ..add(12179)
+ ..add(12180)
+ ..add(12181)
+ ..add(12182)
+ ..add(12183)
+ ..add(12184)
+ ..add(12185)
+ ..add(12186)
+ ..add(12187)
+ ..add(12188)
+ ..add(12189)
+ ..add(12190)
+ ..add(12191)
+ ..add(12192)
+ ..add(12193)
+ ..add(12194)
+ ..add(12195)
+ ..add(12196)
+ ..add(12197)
+ ..add(12198)
+ ..add(12199)
+ ..add(12200)
+ ..add(12201)
+ ..add(12202)
+ ..add(12203)
+ ..add(12204)
+ ..add(12205)
+ ..add(12206)
+ ..add(12207)
+ ..add(12208)
+ ..add(12209)
+ ..add(12210)
+ ..add(12211)
+ ..add(12212)
+ ..add(12213)
+ ..add(12214)
+ ..add(12215)
+ ..add(12216)
+ ..add(12217)
+ ..add(12218)
+ ..add(12219)
+ ..add(12220)
+ ..add(12221)
+ ..add(12222)
+ ..add(12223)
+ ..add(12224)
+ ..add(12225)
+ ..add(12226)
+ ..add(12227)
+ ..add(12228)
+ ..add(12229)
+ ..add(12230)
+ ..add(12231)
+ ..add(12232)
+ ..add(12233)
+ ..add(12234)
+ ..add(12235)
+ ..add(12236)
+ ..add(12237)
+ ..add(12238)
+ ..add(12239)
+ ..add(12240)
+ ..add(12241)
+ ..add(12242)
+ ..add(12243)
+ ..add(12244)
+ ..add(12245)
+ ..add(12246)
+ ..add(12247)
+ ..add(12248)
+ ..add(12249)
+ ..add(12250)
+ ..add(12251)
+ ..add(12252)
+ ..add(12253)
+ ..add(12254)
+ ..add(12255)
+ ..add(12256)
+ ..add(12257)
+ ..add(12258)
+ ..add(12259)
+ ..add(12260)
+ ..add(12261)
+ ..add(12262)
+ ..add(12263)
+ ..add(12264)
+ ..add(12265)
+ ..add(12266)
+ ..add(12267)
+ ..add(12268)
+ ..add(12269)
+ ..add(12270)
+ ..add(12271)
+ ..add(12272)
+ ..add(12273)
+ ..add(12274)
+ ..add(12275)
+ ..add(12276)
+ ..add(12277)
+ ..add(12278)
+ ..add(12279)
+ ..add(12280)
+ ..add(12281)
+ ..add(12282)
+ ..add(12283)
+ ..add(12284)
+ ..add(12285)
+ ..add(12286)
+ ..add(12287)
+ ..add(12288)
+ ..add(12289)
+ ..add(12290)
+ ..add(12291)
+ ..add(12292)
+ ..add(12293)
+ ..add(12294)
+ ..add(12295)
+ ..add(12296)
+ ..add(12297)
+ ..add(12298)
+ ..add(12299)
+ ..add(12300)
+ ..add(12301)
+ ..add(12302)
+ ..add(12303)
+ ..add(12304)
+ ..add(12305)
+ ..add(12306)
+ ..add(12307)
+ ..add(12308)
+ ..add(12309)
+ ..add(12310)
+ ..add(12311)
+ ..add(12312)
+ ..add(12313)
+ ..add(12314)
+ ..add(12315)
+ ..add(12316)
+ ..add(12317)
+ ..add(12318)
+ ..add(12319)
+ ..add(12320)
+ ..add(12321)
+ ..add(12322)
+ ..add(12323)
+ ..add(12324)
+ ..add(12325)
+ ..add(12326)
+ ..add(12327)
+ ..add(12328)
+ ..add(12329)
+ ..add(12330)
+ ..add(12331)
+ ..add(12332)
+ ..add(12333)
+ ..add(12334)
+ ..add(12335)
+ ..add(12336)
+ ..add(12337)
+ ..add(12338)
+ ..add(12339)
+ ..add(12340)
+ ..add(12341)
+ ..add(12342)
+ ..add(12343)
+ ..add(12344)
+ ..add(12345)
+ ..add(12346)
+ ..add(12347)
+ ..add(12348)
+ ..add(12349)
+ ..add(12350)
+ ..add(12351)
+ ..add(12352)
+ ..add(12353)
+ ..add(12354)
+ ..add(12355)
+ ..add(12356)
+ ..add(12357)
+ ..add(12358)
+ ..add(12359)
+ ..add(12360)
+ ..add(12361)
+ ..add(12362)
+ ..add(12363)
+ ..add(12364)
+ ..add(12365)
+ ..add(12366)
+ ..add(12367)
+ ..add(12368)
+ ..add(12369)
+ ..add(12370)
+ ..add(12371)
+ ..add(12372)
+ ..add(12373)
+ ..add(12374)
+ ..add(12375)
+ ..add(12376)
+ ..add(12377)
+ ..add(12378)
+ ..add(12379)
+ ..add(12380)
+ ..add(12381)
+ ..add(12382)
+ ..add(12383)
+ ..add(12384)
+ ..add(12385)
+ ..add(12386)
+ ..add(12387)
+ ..add(12388)
+ ..add(12389)
+ ..add(12390)
+ ..add(12391)
+ ..add(12392)
+ ..add(12393)
+ ..add(12394)
+ ..add(12395)
+ ..add(12396)
+ ..add(12397)
+ ..add(12398)
+ ..add(12399)
+ ..add(12400)
+ ..add(12401)
+ ..add(12402)
+ ..add(12403)
+ ..add(12404)
+ ..add(12405)
+ ..add(12406)
+ ..add(12407)
+ ..add(12408)
+ ..add(12409)
+ ..add(12410)
+ ..add(12411)
+ ..add(12412)
+ ..add(12413)
+ ..add(12414)
+ ..add(12415)
+ ..add(12416)
+ ..add(12417)
+ ..add(12418)
+ ..add(12419)
+ ..add(12420)
+ ..add(12421)
+ ..add(12422)
+ ..add(12423)
+ ..add(12424)
+ ..add(12425)
+ ..add(12426)
+ ..add(12427)
+ ..add(12428)
+ ..add(12429)
+ ..add(12430)
+ ..add(12431)
+ ..add(12432)
+ ..add(12433)
+ ..add(12434)
+ ..add(12435)
+ ..add(12436)
+ ..add(12437)
+ ..add(12438)
+ ..add(12439)
+ ..add(12440)
+ ..add(12441)
+ ..add(12442)
+ ..add(12443)
+ ..add(12444)
+ ..add(12445)
+ ..add(12446)
+ ..add(12447)
+ ..add(12448)
+ ..add(12449)
+ ..add(12450)
+ ..add(12451)
+ ..add(12452)
+ ..add(12453)
+ ..add(12454)
+ ..add(12455)
+ ..add(12456)
+ ..add(12457)
+ ..add(12458)
+ ..add(12459)
+ ..add(12460)
+ ..add(12461)
+ ..add(12462)
+ ..add(12463)
+ ..add(12464)
+ ..add(12465)
+ ..add(12466)
+ ..add(12467)
+ ..add(12468)
+ ..add(12469)
+ ..add(12470)
+ ..add(12471)
+ ..add(12472)
+ ..add(12473)
+ ..add(12474)
+ ..add(12475)
+ ..add(12476)
+ ..add(12477)
+ ..add(12478)
+ ..add(12479)
+ ..add(12480)
+ ..add(12481)
+ ..add(12482)
+ ..add(12483)
+ ..add(12484)
+ ..add(12485)
+ ..add(12486)
+ ..add(12487)
+ ..add(12488)
+ ..add(12489)
+ ..add(12490)
+ ..add(12491)
+ ..add(12492)
+ ..add(12493)
+ ..add(12494)
+ ..add(12495)
+ ..add(12496)
+ ..add(12497)
+ ..add(12498)
+ ..add(12499)
+ ..add(12500)
+ ..add(12501)
+ ..add(12502)
+ ..add(12503)
+ ..add(12504)
+ ..add(12505)
+ ..add(12506)
+ ..add(12507)
+ ..add(12508)
+ ..add(12509)
+ ..add(12510)
+ ..add(12511)
+ ..add(12512)
+ ..add(12513)
+ ..add(12514)
+ ..add(12515)
+ ..add(12516)
+ ..add(12517)
+ ..add(12518)
+ ..add(12519)
+ ..add(12520)
+ ..add(12521)
+ ..add(12522)
+ ..add(12523)
+ ..add(12524)
+ ..add(12525)
+ ..add(12526)
+ ..add(12527)
+ ..add(12528)
+ ..add(12529)
+ ..add(12530)
+ ..add(12531)
+ ..add(12532)
+ ..add(12533)
+ ..add(12534)
+ ..add(12535)
+ ..add(12536)
+ ..add(12537)
+ ..add(12538)
+ ..add(12539)
+ ..add(12540)
+ ..add(12541)
+ ..add(12542)
+ ..add(12543)
+ ..add(12544)
+ ..add(12545)
+ ..add(12546)
+ ..add(12547)
+ ..add(12548)
+ ..add(12549)
+ ..add(12550)
+ ..add(12551)
+ ..add(12552)
+ ..add(12553)
+ ..add(12554)
+ ..add(12555)
+ ..add(12556)
+ ..add(12557)
+ ..add(12558)
+ ..add(12559)
+ ..add(12560)
+ ..add(12561)
+ ..add(12562)
+ ..add(12563)
+ ..add(12564)
+ ..add(12565)
+ ..add(12566)
+ ..add(12567)
+ ..add(12568)
+ ..add(12569)
+ ..add(12570)
+ ..add(12571)
+ ..add(12572)
+ ..add(12573)
+ ..add(12574)
+ ..add(12575)
+ ..add(12576)
+ ..add(12577)
+ ..add(12578)
+ ..add(12579)
+ ..add(12580)
+ ..add(12581)
+ ..add(12582)
+ ..add(12583)
+ ..add(12584)
+ ..add(12585)
+ ..add(12586)
+ ..add(12587)
+ ..add(12588)
+ ..add(12589)
+ ..add(12590)
+ ..add(12591)
+ ..add(12592)
+ ..add(12593)
+ ..add(12594)
+ ..add(12595)
+ ..add(12596)
+ ..add(12597)
+ ..add(12598)
+ ..add(12599)
+ ..add(12600)
+ ..add(12601)
+ ..add(12602)
+ ..add(12603)
+ ..add(12604)
+ ..add(12605)
+ ..add(12606)
+ ..add(12607)
+ ..add(12608)
+ ..add(12609)
+ ..add(12610)
+ ..add(12611)
+ ..add(12612)
+ ..add(12613)
+ ..add(12614)
+ ..add(12615)
+ ..add(12616)
+ ..add(12617)
+ ..add(12618)
+ ..add(12619)
+ ..add(12620)
+ ..add(12621)
+ ..add(12622)
+ ..add(12623)
+ ..add(12624)
+ ..add(12625)
+ ..add(12626)
+ ..add(12627)
+ ..add(12628)
+ ..add(12629)
+ ..add(12630)
+ ..add(12631)
+ ..add(12632)
+ ..add(12633)
+ ..add(12634)
+ ..add(12635)
+ ..add(12636)
+ ..add(12637)
+ ..add(12638)
+ ..add(12639)
+ ..add(12640)
+ ..add(12641)
+ ..add(12642)
+ ..add(12643)
+ ..add(12644)
+ ..add(12645)
+ ..add(12646)
+ ..add(12647)
+ ..add(12648)
+ ..add(12649)
+ ..add(12650)
+ ..add(12651)
+ ..add(12652)
+ ..add(12653)
+ ..add(12654)
+ ..add(12655)
+ ..add(12656)
+ ..add(12657)
+ ..add(12658)
+ ..add(12659)
+ ..add(12660)
+ ..add(12661)
+ ..add(12662)
+ ..add(12663)
+ ..add(12664)
+ ..add(12665)
+ ..add(12666)
+ ..add(12667)
+ ..add(12668)
+ ..add(12669)
+ ..add(12670)
+ ..add(12671)
+ ..add(12672)
+ ..add(12673)
+ ..add(12674)
+ ..add(12675)
+ ..add(12676)
+ ..add(12677)
+ ..add(12678)
+ ..add(12679)
+ ..add(12680)
+ ..add(12681)
+ ..add(12682)
+ ..add(12683)
+ ..add(12684)
+ ..add(12685)
+ ..add(12686)
+ ..add(12687)
+ ..add(12688)
+ ..add(12689)
+ ..add(12690)
+ ..add(12691)
+ ..add(12692)
+ ..add(12693)
+ ..add(12694)
+ ..add(12695)
+ ..add(12696)
+ ..add(12697)
+ ..add(12698)
+ ..add(12699)
+ ..add(12700)
+ ..add(12701)
+ ..add(12702)
+ ..add(12703)
+ ..add(12704)
+ ..add(12705)
+ ..add(12706)
+ ..add(12707)
+ ..add(12708)
+ ..add(12709)
+ ..add(12710)
+ ..add(12711)
+ ..add(12712)
+ ..add(12713)
+ ..add(12714)
+ ..add(12715)
+ ..add(12716)
+ ..add(12717)
+ ..add(12718)
+ ..add(12719)
+ ..add(12720)
+ ..add(12721)
+ ..add(12722)
+ ..add(12723)
+ ..add(12724)
+ ..add(12725)
+ ..add(12726)
+ ..add(12727)
+ ..add(12728)
+ ..add(12729)
+ ..add(12730)
+ ..add(12731)
+ ..add(12732)
+ ..add(12733)
+ ..add(12734)
+ ..add(12735)
+ ..add(12736)
+ ..add(12737)
+ ..add(12738)
+ ..add(12739)
+ ..add(12740)
+ ..add(12741)
+ ..add(12742)
+ ..add(12743)
+ ..add(12744)
+ ..add(12745)
+ ..add(12746)
+ ..add(12747)
+ ..add(12748)
+ ..add(12749)
+ ..add(12750)
+ ..add(12751)
+ ..add(12752)
+ ..add(12753)
+ ..add(12754)
+ ..add(12755)
+ ..add(12756)
+ ..add(12757)
+ ..add(12758)
+ ..add(12759)
+ ..add(12760)
+ ..add(12761)
+ ..add(12762)
+ ..add(12763)
+ ..add(12764)
+ ..add(12765)
+ ..add(12766)
+ ..add(12767)
+ ..add(12768)
+ ..add(12769)
+ ..add(12770)
+ ..add(12771)
+ ..add(12772)
+ ..add(12773)
+ ..add(12774)
+ ..add(12775)
+ ..add(12776)
+ ..add(12777)
+ ..add(12778)
+ ..add(12779)
+ ..add(12780)
+ ..add(12781)
+ ..add(12782)
+ ..add(12783)
+ ..add(12784)
+ ..add(12785)
+ ..add(12786)
+ ..add(12787)
+ ..add(12788)
+ ..add(12789)
+ ..add(12790)
+ ..add(12791)
+ ..add(12792)
+ ..add(12793)
+ ..add(12794)
+ ..add(12795)
+ ..add(12796)
+ ..add(12797)
+ ..add(12798)
+ ..add(12799)
+ ..add(12800)
+ ..add(12801)
+ ..add(12802)
+ ..add(12803)
+ ..add(12804)
+ ..add(12805)
+ ..add(12806)
+ ..add(12807)
+ ..add(12808)
+ ..add(12809)
+ ..add(12810)
+ ..add(12811)
+ ..add(12812)
+ ..add(12813)
+ ..add(12814)
+ ..add(12815)
+ ..add(12816)
+ ..add(12817)
+ ..add(12818)
+ ..add(12819)
+ ..add(12820)
+ ..add(12821)
+ ..add(12822)
+ ..add(12823)
+ ..add(12824)
+ ..add(12825)
+ ..add(12826)
+ ..add(12827)
+ ..add(12828)
+ ..add(12829)
+ ..add(12830)
+ ..add(12831)
+ ..add(12832)
+ ..add(12833)
+ ..add(12834)
+ ..add(12835)
+ ..add(12836)
+ ..add(12837)
+ ..add(12838)
+ ..add(12839)
+ ..add(12840)
+ ..add(12841)
+ ..add(12842)
+ ..add(12843)
+ ..add(12844)
+ ..add(12845)
+ ..add(12846)
+ ..add(12847)
+ ..add(12848)
+ ..add(12849)
+ ..add(12850)
+ ..add(12851)
+ ..add(12852)
+ ..add(12853)
+ ..add(12854)
+ ..add(12855)
+ ..add(12856)
+ ..add(12857)
+ ..add(12858)
+ ..add(12859)
+ ..add(12860)
+ ..add(12861)
+ ..add(12862)
+ ..add(12863)
+ ..add(12864)
+ ..add(12865)
+ ..add(12866)
+ ..add(12867)
+ ..add(12868)
+ ..add(12869)
+ ..add(12870)
+ ..add(12871)
+ ..add(12872)
+ ..add(12873)
+ ..add(12874)
+ ..add(12875)
+ ..add(12876)
+ ..add(12877)
+ ..add(12878)
+ ..add(12879)
+ ..add(12880)
+ ..add(12881)
+ ..add(12882)
+ ..add(12883)
+ ..add(12884)
+ ..add(12885)
+ ..add(12886)
+ ..add(12887)
+ ..add(12888)
+ ..add(12889)
+ ..add(12890)
+ ..add(12891)
+ ..add(12892)
+ ..add(12893)
+ ..add(12894)
+ ..add(12895)
+ ..add(12896)
+ ..add(12897)
+ ..add(12898)
+ ..add(12899)
+ ..add(12900)
+ ..add(12901)
+ ..add(12902)
+ ..add(12903)
+ ..add(12904)
+ ..add(12905)
+ ..add(12906)
+ ..add(12907)
+ ..add(12908)
+ ..add(12909)
+ ..add(12910)
+ ..add(12911)
+ ..add(12912)
+ ..add(12913)
+ ..add(12914)
+ ..add(12915)
+ ..add(12916)
+ ..add(12917)
+ ..add(12918)
+ ..add(12919)
+ ..add(12920)
+ ..add(12921)
+ ..add(12922)
+ ..add(12923)
+ ..add(12924)
+ ..add(12925)
+ ..add(12926)
+ ..add(12927)
+ ..add(12928)
+ ..add(12929)
+ ..add(12930)
+ ..add(12931)
+ ..add(12932)
+ ..add(12933)
+ ..add(12934)
+ ..add(12935)
+ ..add(12936)
+ ..add(12937)
+ ..add(12938)
+ ..add(12939)
+ ..add(12940)
+ ..add(12941)
+ ..add(12942)
+ ..add(12943)
+ ..add(12944)
+ ..add(12945)
+ ..add(12946)
+ ..add(12947)
+ ..add(12948)
+ ..add(12949)
+ ..add(12950)
+ ..add(12951)
+ ..add(12952)
+ ..add(12953)
+ ..add(12954)
+ ..add(12955)
+ ..add(12956)
+ ..add(12957)
+ ..add(12958)
+ ..add(12959)
+ ..add(12960)
+ ..add(12961)
+ ..add(12962)
+ ..add(12963)
+ ..add(12964)
+ ..add(12965)
+ ..add(12966)
+ ..add(12967)
+ ..add(12968)
+ ..add(12969)
+ ..add(12970)
+ ..add(12971)
+ ..add(12972)
+ ..add(12973)
+ ..add(12974)
+ ..add(12975)
+ ..add(12976)
+ ..add(12977)
+ ..add(12978)
+ ..add(12979)
+ ..add(12980)
+ ..add(12981)
+ ..add(12982)
+ ..add(12983)
+ ..add(12984)
+ ..add(12985)
+ ..add(12986)
+ ..add(12987)
+ ..add(12988)
+ ..add(12989)
+ ..add(12990)
+ ..add(12991)
+ ..add(12992)
+ ..add(12993)
+ ..add(12994)
+ ..add(12995)
+ ..add(12996)
+ ..add(12997)
+ ..add(12998)
+ ..add(12999)
+ ..add(13000)
+ ..add(13001)
+ ..add(13002)
+ ..add(13003)
+ ..add(13004)
+ ..add(13005)
+ ..add(13006)
+ ..add(13007)
+ ..add(13008)
+ ..add(13009)
+ ..add(13010)
+ ..add(13011)
+ ..add(13012)
+ ..add(13013)
+ ..add(13014)
+ ..add(13015)
+ ..add(13016)
+ ..add(13017)
+ ..add(13018)
+ ..add(13019)
+ ..add(13020)
+ ..add(13021)
+ ..add(13022)
+ ..add(13023)
+ ..add(13024)
+ ..add(13025)
+ ..add(13026)
+ ..add(13027)
+ ..add(13028)
+ ..add(13029)
+ ..add(13030)
+ ..add(13031)
+ ..add(13032)
+ ..add(13033)
+ ..add(13034)
+ ..add(13035)
+ ..add(13036)
+ ..add(13037)
+ ..add(13038)
+ ..add(13039)
+ ..add(13040)
+ ..add(13041)
+ ..add(13042)
+ ..add(13043)
+ ..add(13044)
+ ..add(13045)
+ ..add(13046)
+ ..add(13047)
+ ..add(13048)
+ ..add(13049)
+ ..add(13050)
+ ..add(13051)
+ ..add(13052)
+ ..add(13053)
+ ..add(13054)
+ ..add(13055)
+ ..add(13056)
+ ..add(13057)
+ ..add(13058)
+ ..add(13059)
+ ..add(13060)
+ ..add(13061)
+ ..add(13062)
+ ..add(13063)
+ ..add(13064)
+ ..add(13065)
+ ..add(13066)
+ ..add(13067)
+ ..add(13068)
+ ..add(13069)
+ ..add(13070)
+ ..add(13071)
+ ..add(13072)
+ ..add(13073)
+ ..add(13074)
+ ..add(13075)
+ ..add(13076)
+ ..add(13077)
+ ..add(13078)
+ ..add(13079)
+ ..add(13080)
+ ..add(13081)
+ ..add(13082)
+ ..add(13083)
+ ..add(13084)
+ ..add(13085)
+ ..add(13086)
+ ..add(13087)
+ ..add(13088)
+ ..add(13089)
+ ..add(13090)
+ ..add(13091)
+ ..add(13092)
+ ..add(13093)
+ ..add(13094)
+ ..add(13095)
+ ..add(13096)
+ ..add(13097)
+ ..add(13098)
+ ..add(13099)
+ ..add(13100)
+ ..add(13101)
+ ..add(13102)
+ ..add(13103)
+ ..add(13104)
+ ..add(13105)
+ ..add(13106)
+ ..add(13107)
+ ..add(13108)
+ ..add(13109)
+ ..add(13110)
+ ..add(13111)
+ ..add(13112)
+ ..add(13113)
+ ..add(13114)
+ ..add(13115)
+ ..add(13116)
+ ..add(13117)
+ ..add(13118)
+ ..add(13119)
+ ..add(13120)
+ ..add(13121)
+ ..add(13122)
+ ..add(13123)
+ ..add(13124)
+ ..add(13125)
+ ..add(13126)
+ ..add(13127)
+ ..add(13128)
+ ..add(13129)
+ ..add(13130)
+ ..add(13131)
+ ..add(13132)
+ ..add(13133)
+ ..add(13134)
+ ..add(13135)
+ ..add(13136)
+ ..add(13137)
+ ..add(13138)
+ ..add(13139)
+ ..add(13140)
+ ..add(13141)
+ ..add(13142)
+ ..add(13143)
+ ..add(13144)
+ ..add(13145)
+ ..add(13146)
+ ..add(13147)
+ ..add(13148)
+ ..add(13149)
+ ..add(13150)
+ ..add(13151)
+ ..add(13152)
+ ..add(13153)
+ ..add(13154)
+ ..add(13155)
+ ..add(13156)
+ ..add(13157)
+ ..add(13158)
+ ..add(13159)
+ ..add(13160)
+ ..add(13161)
+ ..add(13162)
+ ..add(13163)
+ ..add(13164)
+ ..add(13165)
+ ..add(13166)
+ ..add(13167)
+ ..add(13168)
+ ..add(13169)
+ ..add(13170)
+ ..add(13171)
+ ..add(13172)
+ ..add(13173)
+ ..add(13174)
+ ..add(13175)
+ ..add(13176)
+ ..add(13177)
+ ..add(13178)
+ ..add(13179)
+ ..add(13180)
+ ..add(13181)
+ ..add(13182)
+ ..add(13183)
+ ..add(13184)
+ ..add(13185)
+ ..add(13186)
+ ..add(13187)
+ ..add(13188)
+ ..add(13189)
+ ..add(13190)
+ ..add(13191)
+ ..add(13192)
+ ..add(13193)
+ ..add(13194)
+ ..add(13195)
+ ..add(13196)
+ ..add(13197)
+ ..add(13198)
+ ..add(13199)
+ ..add(13200)
+ ..add(13201)
+ ..add(13202)
+ ..add(13203)
+ ..add(13204)
+ ..add(13205)
+ ..add(13206)
+ ..add(13207)
+ ..add(13208)
+ ..add(13209)
+ ..add(13210)
+ ..add(13211)
+ ..add(13212)
+ ..add(13213)
+ ..add(13214)
+ ..add(13215)
+ ..add(13216)
+ ..add(13217)
+ ..add(13218)
+ ..add(13219)
+ ..add(13220)
+ ..add(13221)
+ ..add(13222)
+ ..add(13223)
+ ..add(13224)
+ ..add(13225)
+ ..add(13226)
+ ..add(13227)
+ ..add(13228)
+ ..add(13229)
+ ..add(13230)
+ ..add(13231)
+ ..add(13232)
+ ..add(13233)
+ ..add(13234)
+ ..add(13235)
+ ..add(13236)
+ ..add(13237)
+ ..add(13238)
+ ..add(13239)
+ ..add(13240)
+ ..add(13241)
+ ..add(13242)
+ ..add(13243)
+ ..add(13244)
+ ..add(13245)
+ ..add(13246)
+ ..add(13247)
+ ..add(13248)
+ ..add(13249)
+ ..add(13250)
+ ..add(13251)
+ ..add(13252)
+ ..add(13253)
+ ..add(13254)
+ ..add(13255)
+ ..add(13256)
+ ..add(13257)
+ ..add(13258)
+ ..add(13259)
+ ..add(13260)
+ ..add(13261)
+ ..add(13262)
+ ..add(13263)
+ ..add(13264)
+ ..add(13265)
+ ..add(13266)
+ ..add(13267)
+ ..add(13268)
+ ..add(13269)
+ ..add(13270)
+ ..add(13271)
+ ..add(13272)
+ ..add(13273)
+ ..add(13274)
+ ..add(13275)
+ ..add(13276)
+ ..add(13277)
+ ..add(13278)
+ ..add(13279)
+ ..add(13280)
+ ..add(13281)
+ ..add(13282)
+ ..add(13283)
+ ..add(13284)
+ ..add(13285)
+ ..add(13286)
+ ..add(13287)
+ ..add(13288)
+ ..add(13289)
+ ..add(13290)
+ ..add(13291)
+ ..add(13292)
+ ..add(13293)
+ ..add(13294)
+ ..add(13295)
+ ..add(13296)
+ ..add(13297)
+ ..add(13298)
+ ..add(13299)
+ ..add(13300)
+ ..add(13301)
+ ..add(13302)
+ ..add(13303)
+ ..add(13304)
+ ..add(13305)
+ ..add(13306)
+ ..add(13307)
+ ..add(13308)
+ ..add(13309)
+ ..add(13310)
+ ..add(13311)
+ ..add(13312)
+ ..add(13313)
+ ..add(13314)
+ ..add(13315)
+ ..add(13316)
+ ..add(13317)
+ ..add(13318)
+ ..add(13319)
+ ..add(13320)
+ ..add(13321)
+ ..add(13322)
+ ..add(13323)
+ ..add(13324)
+ ..add(13325)
+ ..add(13326)
+ ..add(13327)
+ ..add(13328)
+ ..add(13329)
+ ..add(13330)
+ ..add(13331)
+ ..add(13332)
+ ..add(13333)
+ ..add(13334)
+ ..add(13335)
+ ..add(13336)
+ ..add(13337)
+ ..add(13338)
+ ..add(13339)
+ ..add(13340)
+ ..add(13341)
+ ..add(13342)
+ ..add(13343)
+ ..add(13344)
+ ..add(13345)
+ ..add(13346)
+ ..add(13347)
+ ..add(13348)
+ ..add(13349)
+ ..add(13350)
+ ..add(13351)
+ ..add(13352)
+ ..add(13353)
+ ..add(13354)
+ ..add(13355)
+ ..add(13356)
+ ..add(13357)
+ ..add(13358)
+ ..add(13359)
+ ..add(13360)
+ ..add(13361)
+ ..add(13362)
+ ..add(13363)
+ ..add(13364)
+ ..add(13365)
+ ..add(13366)
+ ..add(13367)
+ ..add(13368)
+ ..add(13369)
+ ..add(13370)
+ ..add(13371)
+ ..add(13372)
+ ..add(13373)
+ ..add(13374)
+ ..add(13375)
+ ..add(13376)
+ ..add(13377)
+ ..add(13378)
+ ..add(13379)
+ ..add(13380)
+ ..add(13381)
+ ..add(13382)
+ ..add(13383)
+ ..add(13384)
+ ..add(13385)
+ ..add(13386)
+ ..add(13387)
+ ..add(13388)
+ ..add(13389)
+ ..add(13390)
+ ..add(13391)
+ ..add(13392)
+ ..add(13393)
+ ..add(13394)
+ ..add(13395)
+ ..add(13396)
+ ..add(13397)
+ ..add(13398)
+ ..add(13399)
+ ..add(13400)
+ ..add(13401)
+ ..add(13402)
+ ..add(13403)
+ ..add(13404)
+ ..add(13405)
+ ..add(13406)
+ ..add(13407)
+ ..add(13408)
+ ..add(13409)
+ ..add(13410)
+ ..add(13411)
+ ..add(13412)
+ ..add(13413)
+ ..add(13414)
+ ..add(13415)
+ ..add(13416)
+ ..add(13417)
+ ..add(13418)
+ ..add(13419)
+ ..add(13420)
+ ..add(13421)
+ ..add(13422)
+ ..add(13423)
+ ..add(13424)
+ ..add(13425)
+ ..add(13426)
+ ..add(13427)
+ ..add(13428)
+ ..add(13429)
+ ..add(13430)
+ ..add(13431)
+ ..add(13432)
+ ..add(13433)
+ ..add(13434)
+ ..add(13435)
+ ..add(13436)
+ ..add(13437)
+ ..add(13438)
+ ..add(13439)
+ ..add(13440)
+ ..add(13441)
+ ..add(13442)
+ ..add(13443)
+ ..add(13444)
+ ..add(13445)
+ ..add(13446)
+ ..add(13447)
+ ..add(13448)
+ ..add(13449)
+ ..add(13450)
+ ..add(13451)
+ ..add(13452)
+ ..add(13453)
+ ..add(13454)
+ ..add(13455)
+ ..add(13456)
+ ..add(13457)
+ ..add(13458)
+ ..add(13459)
+ ..add(13460)
+ ..add(13461)
+ ..add(13462)
+ ..add(13463)
+ ..add(13464)
+ ..add(13465)
+ ..add(13466)
+ ..add(13467)
+ ..add(13468)
+ ..add(13469)
+ ..add(13470)
+ ..add(13471)
+ ..add(13472)
+ ..add(13473)
+ ..add(13474)
+ ..add(13475)
+ ..add(13476)
+ ..add(13477)
+ ..add(13478)
+ ..add(13479)
+ ..add(13480)
+ ..add(13481)
+ ..add(13482)
+ ..add(13483)
+ ..add(13484)
+ ..add(13485)
+ ..add(13486)
+ ..add(13487)
+ ..add(13488)
+ ..add(13489)
+ ..add(13490)
+ ..add(13491)
+ ..add(13492)
+ ..add(13493)
+ ..add(13494)
+ ..add(13495)
+ ..add(13496)
+ ..add(13497)
+ ..add(13498)
+ ..add(13499)
+ ..add(13500)
+ ..add(13501)
+ ..add(13502)
+ ..add(13503)
+ ..add(13504)
+ ..add(13505)
+ ..add(13506)
+ ..add(13507)
+ ..add(13508)
+ ..add(13509)
+ ..add(13510)
+ ..add(13511)
+ ..add(13512)
+ ..add(13513)
+ ..add(13514)
+ ..add(13515)
+ ..add(13516)
+ ..add(13517)
+ ..add(13518)
+ ..add(13519)
+ ..add(13520)
+ ..add(13521)
+ ..add(13522)
+ ..add(13523)
+ ..add(13524)
+ ..add(13525)
+ ..add(13526)
+ ..add(13527)
+ ..add(13528)
+ ..add(13529)
+ ..add(13530)
+ ..add(13531)
+ ..add(13532)
+ ..add(13533)
+ ..add(13534)
+ ..add(13535)
+ ..add(13536)
+ ..add(13537)
+ ..add(13538)
+ ..add(13539)
+ ..add(13540)
+ ..add(13541)
+ ..add(13542)
+ ..add(13543)
+ ..add(13544)
+ ..add(13545)
+ ..add(13546)
+ ..add(13547)
+ ..add(13548)
+ ..add(13549)
+ ..add(13550)
+ ..add(13551)
+ ..add(13552)
+ ..add(13553)
+ ..add(13554)
+ ..add(13555)
+ ..add(13556)
+ ..add(13557)
+ ..add(13558)
+ ..add(13559)
+ ..add(13560)
+ ..add(13561)
+ ..add(13562)
+ ..add(13563)
+ ..add(13564)
+ ..add(13565)
+ ..add(13566)
+ ..add(13567)
+ ..add(13568)
+ ..add(13569)
+ ..add(13570)
+ ..add(13571)
+ ..add(13572)
+ ..add(13573)
+ ..add(13574)
+ ..add(13575)
+ ..add(13576)
+ ..add(13577)
+ ..add(13578)
+ ..add(13579)
+ ..add(13580)
+ ..add(13581)
+ ..add(13582)
+ ..add(13583)
+ ..add(13584)
+ ..add(13585)
+ ..add(13586)
+ ..add(13587)
+ ..add(13588)
+ ..add(13589)
+ ..add(13590)
+ ..add(13591)
+ ..add(13592)
+ ..add(13593)
+ ..add(13594)
+ ..add(13595)
+ ..add(13596)
+ ..add(13597)
+ ..add(13598)
+ ..add(13599)
+ ..add(13600)
+ ..add(13601)
+ ..add(13602)
+ ..add(13603)
+ ..add(13604)
+ ..add(13605)
+ ..add(13606)
+ ..add(13607)
+ ..add(13608)
+ ..add(13609)
+ ..add(13610)
+ ..add(13611)
+ ..add(13612)
+ ..add(13613)
+ ..add(13614)
+ ..add(13615)
+ ..add(13616)
+ ..add(13617)
+ ..add(13618)
+ ..add(13619)
+ ..add(13620)
+ ..add(13621)
+ ..add(13622)
+ ..add(13623)
+ ..add(13624)
+ ..add(13625)
+ ..add(13626)
+ ..add(13627)
+ ..add(13628)
+ ..add(13629)
+ ..add(13630)
+ ..add(13631)
+ ..add(13632)
+ ..add(13633)
+ ..add(13634)
+ ..add(13635)
+ ..add(13636)
+ ..add(13637)
+ ..add(13638)
+ ..add(13639)
+ ..add(13640)
+ ..add(13641)
+ ..add(13642)
+ ..add(13643)
+ ..add(13644)
+ ..add(13645)
+ ..add(13646)
+ ..add(13647)
+ ..add(13648)
+ ..add(13649)
+ ..add(13650)
+ ..add(13651)
+ ..add(13652)
+ ..add(13653)
+ ..add(13654)
+ ..add(13655)
+ ..add(13656)
+ ..add(13657)
+ ..add(13658)
+ ..add(13659)
+ ..add(13660)
+ ..add(13661)
+ ..add(13662)
+ ..add(13663)
+ ..add(13664)
+ ..add(13665)
+ ..add(13666)
+ ..add(13667)
+ ..add(13668)
+ ..add(13669)
+ ..add(13670)
+ ..add(13671)
+ ..add(13672)
+ ..add(13673)
+ ..add(13674)
+ ..add(13675)
+ ..add(13676)
+ ..add(13677)
+ ..add(13678)
+ ..add(13679)
+ ..add(13680)
+ ..add(13681)
+ ..add(13682)
+ ..add(13683)
+ ..add(13684)
+ ..add(13685)
+ ..add(13686)
+ ..add(13687)
+ ..add(13688)
+ ..add(13689)
+ ..add(13690)
+ ..add(13691)
+ ..add(13692)
+ ..add(13693)
+ ..add(13694)
+ ..add(13695)
+ ..add(13696)
+ ..add(13697)
+ ..add(13698)
+ ..add(13699)
+ ..add(13700)
+ ..add(13701)
+ ..add(13702)
+ ..add(13703)
+ ..add(13704)
+ ..add(13705)
+ ..add(13706)
+ ..add(13707)
+ ..add(13708)
+ ..add(13709)
+ ..add(13710)
+ ..add(13711)
+ ..add(13712)
+ ..add(13713)
+ ..add(13714)
+ ..add(13715)
+ ..add(13716)
+ ..add(13717)
+ ..add(13718)
+ ..add(13719)
+ ..add(13720)
+ ..add(13721)
+ ..add(13722)
+ ..add(13723)
+ ..add(13724)
+ ..add(13725)
+ ..add(13726)
+ ..add(13727)
+ ..add(13728)
+ ..add(13729)
+ ..add(13730)
+ ..add(13731)
+ ..add(13732)
+ ..add(13733)
+ ..add(13734)
+ ..add(13735)
+ ..add(13736)
+ ..add(13737)
+ ..add(13738)
+ ..add(13739)
+ ..add(13740)
+ ..add(13741)
+ ..add(13742)
+ ..add(13743)
+ ..add(13744)
+ ..add(13745)
+ ..add(13746)
+ ..add(13747)
+ ..add(13748)
+ ..add(13749)
+ ..add(13750)
+ ..add(13751)
+ ..add(13752)
+ ..add(13753)
+ ..add(13754)
+ ..add(13755)
+ ..add(13756)
+ ..add(13757)
+ ..add(13758)
+ ..add(13759)
+ ..add(13760)
+ ..add(13761)
+ ..add(13762)
+ ..add(13763)
+ ..add(13764)
+ ..add(13765)
+ ..add(13766)
+ ..add(13767)
+ ..add(13768)
+ ..add(13769)
+ ..add(13770)
+ ..add(13771)
+ ..add(13772)
+ ..add(13773)
+ ..add(13774)
+ ..add(13775)
+ ..add(13776)
+ ..add(13777)
+ ..add(13778)
+ ..add(13779)
+ ..add(13780)
+ ..add(13781)
+ ..add(13782)
+ ..add(13783)
+ ..add(13784)
+ ..add(13785)
+ ..add(13786)
+ ..add(13787)
+ ..add(13788)
+ ..add(13789)
+ ..add(13790)
+ ..add(13791)
+ ..add(13792)
+ ..add(13793)
+ ..add(13794)
+ ..add(13795)
+ ..add(13796)
+ ..add(13797)
+ ..add(13798)
+ ..add(13799)
+ ..add(13800)
+ ..add(13801)
+ ..add(13802)
+ ..add(13803)
+ ..add(13804)
+ ..add(13805)
+ ..add(13806)
+ ..add(13807)
+ ..add(13808)
+ ..add(13809)
+ ..add(13810)
+ ..add(13811)
+ ..add(13812)
+ ..add(13813)
+ ..add(13814)
+ ..add(13815)
+ ..add(13816)
+ ..add(13817)
+ ..add(13818)
+ ..add(13819)
+ ..add(13820)
+ ..add(13821)
+ ..add(13822)
+ ..add(13823)
+ ..add(13824)
+ ..add(13825)
+ ..add(13826)
+ ..add(13827)
+ ..add(13828)
+ ..add(13829)
+ ..add(13830)
+ ..add(13831)
+ ..add(13832)
+ ..add(13833)
+ ..add(13834)
+ ..add(13835)
+ ..add(13836)
+ ..add(13837)
+ ..add(13838)
+ ..add(13839)
+ ..add(13840)
+ ..add(13841)
+ ..add(13842)
+ ..add(13843)
+ ..add(13844)
+ ..add(13845)
+ ..add(13846)
+ ..add(13847)
+ ..add(13848)
+ ..add(13849)
+ ..add(13850)
+ ..add(13851)
+ ..add(13852)
+ ..add(13853)
+ ..add(13854)
+ ..add(13855)
+ ..add(13856)
+ ..add(13857)
+ ..add(13858)
+ ..add(13859)
+ ..add(13860)
+ ..add(13861)
+ ..add(13862)
+ ..add(13863)
+ ..add(13864)
+ ..add(13865)
+ ..add(13866)
+ ..add(13867)
+ ..add(13868)
+ ..add(13869)
+ ..add(13870)
+ ..add(13871)
+ ..add(13872)
+ ..add(13873)
+ ..add(13874)
+ ..add(13875)
+ ..add(13876)
+ ..add(13877)
+ ..add(13878)
+ ..add(13879)
+ ..add(13880)
+ ..add(13881)
+ ..add(13882)
+ ..add(13883)
+ ..add(13884)
+ ..add(13885)
+ ..add(13886)
+ ..add(13887)
+ ..add(13888)
+ ..add(13889)
+ ..add(13890)
+ ..add(13891)
+ ..add(13892)
+ ..add(13893)
+ ..add(13894)
+ ..add(13895)
+ ..add(13896)
+ ..add(13897)
+ ..add(13898)
+ ..add(13899)
+ ..add(13900)
+ ..add(13901)
+ ..add(13902)
+ ..add(13903)
+ ..add(13904)
+ ..add(13905)
+ ..add(13906)
+ ..add(13907)
+ ..add(13908)
+ ..add(13909)
+ ..add(13910)
+ ..add(13911)
+ ..add(13912)
+ ..add(13913)
+ ..add(13914)
+ ..add(13915)
+ ..add(13916)
+ ..add(13917)
+ ..add(13918)
+ ..add(13919)
+ ..add(13920)
+ ..add(13921)
+ ..add(13922)
+ ..add(13923)
+ ..add(13924)
+ ..add(13925)
+ ..add(13926)
+ ..add(13927)
+ ..add(13928)
+ ..add(13929)
+ ..add(13930)
+ ..add(13931)
+ ..add(13932)
+ ..add(13933)
+ ..add(13934)
+ ..add(13935)
+ ..add(13936)
+ ..add(13937)
+ ..add(13938)
+ ..add(13939)
+ ..add(13940)
+ ..add(13941)
+ ..add(13942)
+ ..add(13943)
+ ..add(13944)
+ ..add(13945)
+ ..add(13946)
+ ..add(13947)
+ ..add(13948)
+ ..add(13949)
+ ..add(13950)
+ ..add(13951)
+ ..add(13952)
+ ..add(13953)
+ ..add(13954)
+ ..add(13955)
+ ..add(13956)
+ ..add(13957)
+ ..add(13958)
+ ..add(13959)
+ ..add(13960)
+ ..add(13961)
+ ..add(13962)
+ ..add(13963)
+ ..add(13964)
+ ..add(13965)
+ ..add(13966)
+ ..add(13967)
+ ..add(13968)
+ ..add(13969)
+ ..add(13970)
+ ..add(13971)
+ ..add(13972)
+ ..add(13973)
+ ..add(13974)
+ ..add(13975)
+ ..add(13976)
+ ..add(13977)
+ ..add(13978)
+ ..add(13979)
+ ..add(13980)
+ ..add(13981)
+ ..add(13982)
+ ..add(13983)
+ ..add(13984)
+ ..add(13985)
+ ..add(13986)
+ ..add(13987)
+ ..add(13988)
+ ..add(13989)
+ ..add(13990)
+ ..add(13991)
+ ..add(13992)
+ ..add(13993)
+ ..add(13994)
+ ..add(13995)
+ ..add(13996)
+ ..add(13997)
+ ..add(13998)
+ ..add(13999)
+ ..add(14000)
+ ..add(14001)
+ ..add(14002)
+ ..add(14003)
+ ..add(14004)
+ ..add(14005)
+ ..add(14006)
+ ..add(14007)
+ ..add(14008)
+ ..add(14009)
+ ..add(14010)
+ ..add(14011)
+ ..add(14012)
+ ..add(14013)
+ ..add(14014)
+ ..add(14015)
+ ..add(14016)
+ ..add(14017)
+ ..add(14018)
+ ..add(14019)
+ ..add(14020)
+ ..add(14021)
+ ..add(14022)
+ ..add(14023)
+ ..add(14024)
+ ..add(14025)
+ ..add(14026)
+ ..add(14027)
+ ..add(14028)
+ ..add(14029)
+ ..add(14030)
+ ..add(14031)
+ ..add(14032)
+ ..add(14033)
+ ..add(14034)
+ ..add(14035)
+ ..add(14036)
+ ..add(14037)
+ ..add(14038)
+ ..add(14039)
+ ..add(14040)
+ ..add(14041)
+ ..add(14042)
+ ..add(14043)
+ ..add(14044)
+ ..add(14045)
+ ..add(14046)
+ ..add(14047)
+ ..add(14048)
+ ..add(14049)
+ ..add(14050)
+ ..add(14051)
+ ..add(14052)
+ ..add(14053)
+ ..add(14054)
+ ..add(14055)
+ ..add(14056)
+ ..add(14057)
+ ..add(14058)
+ ..add(14059)
+ ..add(14060)
+ ..add(14061)
+ ..add(14062)
+ ..add(14063)
+ ..add(14064)
+ ..add(14065)
+ ..add(14066)
+ ..add(14067)
+ ..add(14068)
+ ..add(14069)
+ ..add(14070)
+ ..add(14071)
+ ..add(14072)
+ ..add(14073)
+ ..add(14074)
+ ..add(14075)
+ ..add(14076)
+ ..add(14077)
+ ..add(14078)
+ ..add(14079)
+ ..add(14080)
+ ..add(14081)
+ ..add(14082)
+ ..add(14083)
+ ..add(14084)
+ ..add(14085)
+ ..add(14086)
+ ..add(14087)
+ ..add(14088)
+ ..add(14089)
+ ..add(14090)
+ ..add(14091)
+ ..add(14092)
+ ..add(14093)
+ ..add(14094)
+ ..add(14095)
+ ..add(14096)
+ ..add(14097)
+ ..add(14098)
+ ..add(14099)
+ ..add(14100)
+ ..add(14101)
+ ..add(14102)
+ ..add(14103)
+ ..add(14104)
+ ..add(14105)
+ ..add(14106)
+ ..add(14107)
+ ..add(14108)
+ ..add(14109)
+ ..add(14110)
+ ..add(14111)
+ ..add(14112)
+ ..add(14113)
+ ..add(14114)
+ ..add(14115)
+ ..add(14116)
+ ..add(14117)
+ ..add(14118)
+ ..add(14119)
+ ..add(14120)
+ ..add(14121)
+ ..add(14122)
+ ..add(14123)
+ ..add(14124)
+ ..add(14125)
+ ..add(14126)
+ ..add(14127)
+ ..add(14128)
+ ..add(14129)
+ ..add(14130)
+ ..add(14131)
+ ..add(14132)
+ ..add(14133)
+ ..add(14134)
+ ..add(14135)
+ ..add(14136)
+ ..add(14137)
+ ..add(14138)
+ ..add(14139)
+ ..add(14140)
+ ..add(14141)
+ ..add(14142)
+ ..add(14143)
+ ..add(14144)
+ ..add(14145)
+ ..add(14146)
+ ..add(14147)
+ ..add(14148)
+ ..add(14149)
+ ..add(14150)
+ ..add(14151)
+ ..add(14152)
+ ..add(14153)
+ ..add(14154)
+ ..add(14155)
+ ..add(14156)
+ ..add(14157)
+ ..add(14158)
+ ..add(14159)
+ ..add(14160)
+ ..add(14161)
+ ..add(14162)
+ ..add(14163)
+ ..add(14164)
+ ..add(14165)
+ ..add(14166)
+ ..add(14167)
+ ..add(14168)
+ ..add(14169)
+ ..add(14170)
+ ..add(14171)
+ ..add(14172)
+ ..add(14173)
+ ..add(14174)
+ ..add(14175)
+ ..add(14176)
+ ..add(14177)
+ ..add(14178)
+ ..add(14179)
+ ..add(14180)
+ ..add(14181)
+ ..add(14182)
+ ..add(14183)
+ ..add(14184)
+ ..add(14185)
+ ..add(14186)
+ ..add(14187)
+ ..add(14188)
+ ..add(14189)
+ ..add(14190)
+ ..add(14191)
+ ..add(14192)
+ ..add(14193)
+ ..add(14194)
+ ..add(14195)
+ ..add(14196)
+ ..add(14197)
+ ..add(14198)
+ ..add(14199)
+ ..add(14200)
+ ..add(14201)
+ ..add(14202)
+ ..add(14203)
+ ..add(14204)
+ ..add(14205)
+ ..add(14206)
+ ..add(14207)
+ ..add(14208)
+ ..add(14209)
+ ..add(14210)
+ ..add(14211)
+ ..add(14212)
+ ..add(14213)
+ ..add(14214)
+ ..add(14215)
+ ..add(14216)
+ ..add(14217)
+ ..add(14218)
+ ..add(14219)
+ ..add(14220)
+ ..add(14221)
+ ..add(14222)
+ ..add(14223)
+ ..add(14224)
+ ..add(14225)
+ ..add(14226)
+ ..add(14227)
+ ..add(14228)
+ ..add(14229)
+ ..add(14230)
+ ..add(14231)
+ ..add(14232)
+ ..add(14233)
+ ..add(14234)
+ ..add(14235)
+ ..add(14236)
+ ..add(14237)
+ ..add(14238)
+ ..add(14239)
+ ..add(14240)
+ ..add(14241)
+ ..add(14242)
+ ..add(14243)
+ ..add(14244)
+ ..add(14245)
+ ..add(14246)
+ ..add(14247)
+ ..add(14248)
+ ..add(14249)
+ ..add(14250)
+ ..add(14251)
+ ..add(14252)
+ ..add(14253)
+ ..add(14254)
+ ..add(14255)
+ ..add(14256)
+ ..add(14257)
+ ..add(14258)
+ ..add(14259)
+ ..add(14260)
+ ..add(14261)
+ ..add(14262)
+ ..add(14263)
+ ..add(14264)
+ ..add(14265)
+ ..add(14266)
+ ..add(14267)
+ ..add(14268)
+ ..add(14269)
+ ..add(14270)
+ ..add(14271)
+ ..add(14272)
+ ..add(14273)
+ ..add(14274)
+ ..add(14275)
+ ..add(14276)
+ ..add(14277)
+ ..add(14278)
+ ..add(14279)
+ ..add(14280)
+ ..add(14281)
+ ..add(14282)
+ ..add(14283)
+ ..add(14284)
+ ..add(14285)
+ ..add(14286)
+ ..add(14287)
+ ..add(14288)
+ ..add(14289)
+ ..add(14290)
+ ..add(14291)
+ ..add(14292)
+ ..add(14293)
+ ..add(14294)
+ ..add(14295)
+ ..add(14296)
+ ..add(14297)
+ ..add(14298)
+ ..add(14299)
+ ..add(14300)
+ ..add(14301)
+ ..add(14302)
+ ..add(14303)
+ ..add(14304)
+ ..add(14305)
+ ..add(14306)
+ ..add(14307)
+ ..add(14308)
+ ..add(14309)
+ ..add(14310)
+ ..add(14311)
+ ..add(14312)
+ ..add(14313)
+ ..add(14314)
+ ..add(14315)
+ ..add(14316)
+ ..add(14317)
+ ..add(14318)
+ ..add(14319)
+ ..add(14320)
+ ..add(14321)
+ ..add(14322)
+ ..add(14323)
+ ..add(14324)
+ ..add(14325)
+ ..add(14326)
+ ..add(14327)
+ ..add(14328)
+ ..add(14329)
+ ..add(14330)
+ ..add(14331)
+ ..add(14332)
+ ..add(14333)
+ ..add(14334)
+ ..add(14335)
+ ..add(14336)
+ ..add(14337)
+ ..add(14338)
+ ..add(14339)
+ ..add(14340)
+ ..add(14341)
+ ..add(14342)
+ ..add(14343)
+ ..add(14344)
+ ..add(14345)
+ ..add(14346)
+ ..add(14347)
+ ..add(14348)
+ ..add(14349)
+ ..add(14350)
+ ..add(14351)
+ ..add(14352)
+ ..add(14353)
+ ..add(14354)
+ ..add(14355)
+ ..add(14356)
+ ..add(14357)
+ ..add(14358)
+ ..add(14359)
+ ..add(14360)
+ ..add(14361)
+ ..add(14362)
+ ..add(14363)
+ ..add(14364)
+ ..add(14365)
+ ..add(14366)
+ ..add(14367)
+ ..add(14368)
+ ..add(14369)
+ ..add(14370)
+ ..add(14371)
+ ..add(14372)
+ ..add(14373)
+ ..add(14374)
+ ..add(14375)
+ ..add(14376)
+ ..add(14377)
+ ..add(14378)
+ ..add(14379)
+ ..add(14380)
+ ..add(14381)
+ ..add(14382)
+ ..add(14383)
+ ..add(14384)
+ ..add(14385)
+ ..add(14386)
+ ..add(14387)
+ ..add(14388)
+ ..add(14389)
+ ..add(14390)
+ ..add(14391)
+ ..add(14392)
+ ..add(14393)
+ ..add(14394)
+ ..add(14395)
+ ..add(14396)
+ ..add(14397)
+ ..add(14398)
+ ..add(14399)
+ ..add(14400)
+ ..add(14401)
+ ..add(14402)
+ ..add(14403)
+ ..add(14404)
+ ..add(14405)
+ ..add(14406)
+ ..add(14407)
+ ..add(14408)
+ ..add(14409)
+ ..add(14410)
+ ..add(14411)
+ ..add(14412)
+ ..add(14413)
+ ..add(14414)
+ ..add(14415)
+ ..add(14416)
+ ..add(14417)
+ ..add(14418)
+ ..add(14419)
+ ..add(14420)
+ ..add(14421)
+ ..add(14422)
+ ..add(14423)
+ ..add(14424)
+ ..add(14425)
+ ..add(14426)
+ ..add(14427)
+ ..add(14428)
+ ..add(14429)
+ ..add(14430)
+ ..add(14431)
+ ..add(14432)
+ ..add(14433)
+ ..add(14434)
+ ..add(14435)
+ ..add(14436)
+ ..add(14437)
+ ..add(14438)
+ ..add(14439)
+ ..add(14440)
+ ..add(14441)
+ ..add(14442)
+ ..add(14443)
+ ..add(14444)
+ ..add(14445)
+ ..add(14446)
+ ..add(14447)
+ ..add(14448)
+ ..add(14449)
+ ..add(14450)
+ ..add(14451)
+ ..add(14452)
+ ..add(14453)
+ ..add(14454)
+ ..add(14455)
+ ..add(14456)
+ ..add(14457)
+ ..add(14458)
+ ..add(14459)
+ ..add(14460)
+ ..add(14461)
+ ..add(14462)
+ ..add(14463)
+ ..add(14464)
+ ..add(14465)
+ ..add(14466)
+ ..add(14467)
+ ..add(14468)
+ ..add(14469)
+ ..add(14470)
+ ..add(14471)
+ ..add(14472)
+ ..add(14473)
+ ..add(14474)
+ ..add(14475)
+ ..add(14476)
+ ..add(14477)
+ ..add(14478)
+ ..add(14479)
+ ..add(14480)
+ ..add(14481)
+ ..add(14482)
+ ..add(14483)
+ ..add(14484)
+ ..add(14485)
+ ..add(14486)
+ ..add(14487)
+ ..add(14488)
+ ..add(14489)
+ ..add(14490)
+ ..add(14491)
+ ..add(14492)
+ ..add(14493)
+ ..add(14494)
+ ..add(14495)
+ ..add(14496)
+ ..add(14497)
+ ..add(14498)
+ ..add(14499)
+ ..add(14500)
+ ..add(14501)
+ ..add(14502)
+ ..add(14503)
+ ..add(14504)
+ ..add(14505)
+ ..add(14506)
+ ..add(14507)
+ ..add(14508)
+ ..add(14509)
+ ..add(14510)
+ ..add(14511)
+ ..add(14512)
+ ..add(14513)
+ ..add(14514)
+ ..add(14515)
+ ..add(14516)
+ ..add(14517)
+ ..add(14518)
+ ..add(14519)
+ ..add(14520)
+ ..add(14521)
+ ..add(14522)
+ ..add(14523)
+ ..add(14524)
+ ..add(14525)
+ ..add(14526)
+ ..add(14527)
+ ..add(14528)
+ ..add(14529)
+ ..add(14530)
+ ..add(14531)
+ ..add(14532)
+ ..add(14533)
+ ..add(14534)
+ ..add(14535)
+ ..add(14536)
+ ..add(14537)
+ ..add(14538)
+ ..add(14539)
+ ..add(14540)
+ ..add(14541)
+ ..add(14542)
+ ..add(14543)
+ ..add(14544)
+ ..add(14545)
+ ..add(14546)
+ ..add(14547)
+ ..add(14548)
+ ..add(14549)
+ ..add(14550)
+ ..add(14551)
+ ..add(14552)
+ ..add(14553)
+ ..add(14554)
+ ..add(14555)
+ ..add(14556)
+ ..add(14557)
+ ..add(14558)
+ ..add(14559)
+ ..add(14560)
+ ..add(14561)
+ ..add(14562)
+ ..add(14563)
+ ..add(14564)
+ ..add(14565)
+ ..add(14566)
+ ..add(14567)
+ ..add(14568)
+ ..add(14569)
+ ..add(14570)
+ ..add(14571)
+ ..add(14572)
+ ..add(14573)
+ ..add(14574)
+ ..add(14575)
+ ..add(14576)
+ ..add(14577)
+ ..add(14578)
+ ..add(14579)
+ ..add(14580)
+ ..add(14581)
+ ..add(14582)
+ ..add(14583)
+ ..add(14584)
+ ..add(14585)
+ ..add(14586)
+ ..add(14587)
+ ..add(14588)
+ ..add(14589)
+ ..add(14590)
+ ..add(14591)
+ ..add(14592)
+ ..add(14593)
+ ..add(14594)
+ ..add(14595)
+ ..add(14596)
+ ..add(14597)
+ ..add(14598)
+ ..add(14599)
+ ..add(14600)
+ ..add(14601)
+ ..add(14602)
+ ..add(14603)
+ ..add(14604)
+ ..add(14605)
+ ..add(14606)
+ ..add(14607)
+ ..add(14608)
+ ..add(14609)
+ ..add(14610)
+ ..add(14611)
+ ..add(14612)
+ ..add(14613)
+ ..add(14614)
+ ..add(14615)
+ ..add(14616)
+ ..add(14617)
+ ..add(14618)
+ ..add(14619)
+ ..add(14620)
+ ..add(14621)
+ ..add(14622)
+ ..add(14623)
+ ..add(14624)
+ ..add(14625)
+ ..add(14626)
+ ..add(14627)
+ ..add(14628)
+ ..add(14629)
+ ..add(14630)
+ ..add(14631)
+ ..add(14632)
+ ..add(14633)
+ ..add(14634)
+ ..add(14635)
+ ..add(14636)
+ ..add(14637)
+ ..add(14638)
+ ..add(14639)
+ ..add(14640)
+ ..add(14641)
+ ..add(14642)
+ ..add(14643)
+ ..add(14644)
+ ..add(14645)
+ ..add(14646)
+ ..add(14647)
+ ..add(14648)
+ ..add(14649)
+ ..add(14650)
+ ..add(14651)
+ ..add(14652)
+ ..add(14653)
+ ..add(14654)
+ ..add(14655)
+ ..add(14656)
+ ..add(14657)
+ ..add(14658)
+ ..add(14659)
+ ..add(14660)
+ ..add(14661)
+ ..add(14662)
+ ..add(14663)
+ ..add(14664)
+ ..add(14665)
+ ..add(14666)
+ ..add(14667)
+ ..add(14668)
+ ..add(14669)
+ ..add(14670)
+ ..add(14671)
+ ..add(14672)
+ ..add(14673)
+ ..add(14674)
+ ..add(14675)
+ ..add(14676)
+ ..add(14677)
+ ..add(14678)
+ ..add(14679)
+ ..add(14680)
+ ..add(14681)
+ ..add(14682)
+ ..add(14683)
+ ..add(14684)
+ ..add(14685)
+ ..add(14686)
+ ..add(14687)
+ ..add(14688)
+ ..add(14689)
+ ..add(14690)
+ ..add(14691)
+ ..add(14692)
+ ..add(14693)
+ ..add(14694)
+ ..add(14695)
+ ..add(14696)
+ ..add(14697)
+ ..add(14698)
+ ..add(14699)
+ ..add(14700)
+ ..add(14701)
+ ..add(14702)
+ ..add(14703)
+ ..add(14704)
+ ..add(14705)
+ ..add(14706)
+ ..add(14707)
+ ..add(14708)
+ ..add(14709)
+ ..add(14710)
+ ..add(14711)
+ ..add(14712)
+ ..add(14713)
+ ..add(14714)
+ ..add(14715)
+ ..add(14716)
+ ..add(14717)
+ ..add(14718)
+ ..add(14719)
+ ..add(14720)
+ ..add(14721)
+ ..add(14722)
+ ..add(14723)
+ ..add(14724)
+ ..add(14725)
+ ..add(14726)
+ ..add(14727)
+ ..add(14728)
+ ..add(14729)
+ ..add(14730)
+ ..add(14731)
+ ..add(14732)
+ ..add(14733)
+ ..add(14734)
+ ..add(14735)
+ ..add(14736)
+ ..add(14737)
+ ..add(14738)
+ ..add(14739)
+ ..add(14740)
+ ..add(14741)
+ ..add(14742)
+ ..add(14743)
+ ..add(14744)
+ ..add(14745)
+ ..add(14746)
+ ..add(14747)
+ ..add(14748)
+ ..add(14749)
+ ..add(14750)
+ ..add(14751)
+ ..add(14752)
+ ..add(14753)
+ ..add(14754)
+ ..add(14755)
+ ..add(14756)
+ ..add(14757)
+ ..add(14758)
+ ..add(14759)
+ ..add(14760)
+ ..add(14761)
+ ..add(14762)
+ ..add(14763)
+ ..add(14764)
+ ..add(14765)
+ ..add(14766)
+ ..add(14767)
+ ..add(14768)
+ ..add(14769)
+ ..add(14770)
+ ..add(14771)
+ ..add(14772)
+ ..add(14773)
+ ..add(14774)
+ ..add(14775)
+ ..add(14776)
+ ..add(14777)
+ ..add(14778)
+ ..add(14779)
+ ..add(14780)
+ ..add(14781)
+ ..add(14782)
+ ..add(14783)
+ ..add(14784)
+ ..add(14785)
+ ..add(14786)
+ ..add(14787)
+ ..add(14788)
+ ..add(14789)
+ ..add(14790)
+ ..add(14791)
+ ..add(14792)
+ ..add(14793)
+ ..add(14794)
+ ..add(14795)
+ ..add(14796)
+ ..add(14797)
+ ..add(14798)
+ ..add(14799)
+ ..add(14800)
+ ..add(14801)
+ ..add(14802)
+ ..add(14803)
+ ..add(14804)
+ ..add(14805)
+ ..add(14806)
+ ..add(14807)
+ ..add(14808)
+ ..add(14809)
+ ..add(14810)
+ ..add(14811)
+ ..add(14812)
+ ..add(14813)
+ ..add(14814)
+ ..add(14815)
+ ..add(14816)
+ ..add(14817)
+ ..add(14818)
+ ..add(14819)
+ ..add(14820)
+ ..add(14821)
+ ..add(14822)
+ ..add(14823)
+ ..add(14824)
+ ..add(14825)
+ ..add(14826)
+ ..add(14827)
+ ..add(14828)
+ ..add(14829)
+ ..add(14830)
+ ..add(14831)
+ ..add(14832)
+ ..add(14833)
+ ..add(14834)
+ ..add(14835)
+ ..add(14836)
+ ..add(14837)
+ ..add(14838)
+ ..add(14839)
+ ..add(14840)
+ ..add(14841)
+ ..add(14842)
+ ..add(14843)
+ ..add(14844)
+ ..add(14845)
+ ..add(14846)
+ ..add(14847)
+ ..add(14848)
+ ..add(14849)
+ ..add(14850)
+ ..add(14851)
+ ..add(14852)
+ ..add(14853)
+ ..add(14854)
+ ..add(14855)
+ ..add(14856)
+ ..add(14857)
+ ..add(14858)
+ ..add(14859)
+ ..add(14860)
+ ..add(14861)
+ ..add(14862)
+ ..add(14863)
+ ..add(14864)
+ ..add(14865)
+ ..add(14866)
+ ..add(14867)
+ ..add(14868)
+ ..add(14869)
+ ..add(14870)
+ ..add(14871)
+ ..add(14872)
+ ..add(14873)
+ ..add(14874)
+ ..add(14875)
+ ..add(14876)
+ ..add(14877)
+ ..add(14878)
+ ..add(14879)
+ ..add(14880)
+ ..add(14881)
+ ..add(14882)
+ ..add(14883)
+ ..add(14884)
+ ..add(14885)
+ ..add(14886)
+ ..add(14887)
+ ..add(14888)
+ ..add(14889)
+ ..add(14890)
+ ..add(14891)
+ ..add(14892)
+ ..add(14893)
+ ..add(14894)
+ ..add(14895)
+ ..add(14896)
+ ..add(14897)
+ ..add(14898)
+ ..add(14899)
+ ..add(14900)
+ ..add(14901)
+ ..add(14902)
+ ..add(14903)
+ ..add(14904)
+ ..add(14905)
+ ..add(14906)
+ ..add(14907)
+ ..add(14908)
+ ..add(14909)
+ ..add(14910)
+ ..add(14911)
+ ..add(14912)
+ ..add(14913)
+ ..add(14914)
+ ..add(14915)
+ ..add(14916)
+ ..add(14917)
+ ..add(14918)
+ ..add(14919)
+ ..add(14920)
+ ..add(14921)
+ ..add(14922)
+ ..add(14923)
+ ..add(14924)
+ ..add(14925)
+ ..add(14926)
+ ..add(14927)
+ ..add(14928)
+ ..add(14929)
+ ..add(14930)
+ ..add(14931)
+ ..add(14932)
+ ..add(14933)
+ ..add(14934)
+ ..add(14935)
+ ..add(14936)
+ ..add(14937)
+ ..add(14938)
+ ..add(14939)
+ ..add(14940)
+ ..add(14941)
+ ..add(14942)
+ ..add(14943)
+ ..add(14944)
+ ..add(14945)
+ ..add(14946)
+ ..add(14947)
+ ..add(14948)
+ ..add(14949)
+ ..add(14950)
+ ..add(14951)
+ ..add(14952)
+ ..add(14953)
+ ..add(14954)
+ ..add(14955)
+ ..add(14956)
+ ..add(14957)
+ ..add(14958)
+ ..add(14959)
+ ..add(14960)
+ ..add(14961)
+ ..add(14962)
+ ..add(14963)
+ ..add(14964)
+ ..add(14965)
+ ..add(14966)
+ ..add(14967)
+ ..add(14968)
+ ..add(14969)
+ ..add(14970)
+ ..add(14971)
+ ..add(14972)
+ ..add(14973)
+ ..add(14974)
+ ..add(14975)
+ ..add(14976)
+ ..add(14977)
+ ..add(14978)
+ ..add(14979)
+ ..add(14980)
+ ..add(14981)
+ ..add(14982)
+ ..add(14983)
+ ..add(14984)
+ ..add(14985)
+ ..add(14986)
+ ..add(14987)
+ ..add(14988)
+ ..add(14989)
+ ..add(14990)
+ ..add(14991)
+ ..add(14992)
+ ..add(14993)
+ ..add(14994)
+ ..add(14995)
+ ..add(14996)
+ ..add(14997)
+ ..add(14998)
+ ..add(14999)
+ ..add(15000)
+ ..add(15001)
+ ..add(15002)
+ ..add(15003)
+ ..add(15004)
+ ..add(15005)
+ ..add(15006)
+ ..add(15007)
+ ..add(15008)
+ ..add(15009)
+ ..add(15010)
+ ..add(15011)
+ ..add(15012)
+ ..add(15013)
+ ..add(15014)
+ ..add(15015)
+ ..add(15016)
+ ..add(15017)
+ ..add(15018)
+ ..add(15019)
+ ..add(15020)
+ ..add(15021)
+ ..add(15022)
+ ..add(15023)
+ ..add(15024)
+ ..add(15025)
+ ..add(15026)
+ ..add(15027)
+ ..add(15028)
+ ..add(15029)
+ ..add(15030)
+ ..add(15031)
+ ..add(15032)
+ ..add(15033)
+ ..add(15034)
+ ..add(15035)
+ ..add(15036)
+ ..add(15037)
+ ..add(15038)
+ ..add(15039)
+ ..add(15040)
+ ..add(15041)
+ ..add(15042)
+ ..add(15043)
+ ..add(15044)
+ ..add(15045)
+ ..add(15046)
+ ..add(15047)
+ ..add(15048)
+ ..add(15049)
+ ..add(15050)
+ ..add(15051)
+ ..add(15052)
+ ..add(15053)
+ ..add(15054)
+ ..add(15055)
+ ..add(15056)
+ ..add(15057)
+ ..add(15058)
+ ..add(15059)
+ ..add(15060)
+ ..add(15061)
+ ..add(15062)
+ ..add(15063)
+ ..add(15064)
+ ..add(15065)
+ ..add(15066)
+ ..add(15067)
+ ..add(15068)
+ ..add(15069)
+ ..add(15070)
+ ..add(15071)
+ ..add(15072)
+ ..add(15073)
+ ..add(15074)
+ ..add(15075)
+ ..add(15076)
+ ..add(15077)
+ ..add(15078)
+ ..add(15079)
+ ..add(15080)
+ ..add(15081)
+ ..add(15082)
+ ..add(15083)
+ ..add(15084)
+ ..add(15085)
+ ..add(15086)
+ ..add(15087)
+ ..add(15088)
+ ..add(15089)
+ ..add(15090)
+ ..add(15091)
+ ..add(15092)
+ ..add(15093)
+ ..add(15094)
+ ..add(15095)
+ ..add(15096)
+ ..add(15097)
+ ..add(15098)
+ ..add(15099)
+ ..add(15100)
+ ..add(15101)
+ ..add(15102)
+ ..add(15103)
+ ..add(15104)
+ ..add(15105)
+ ..add(15106)
+ ..add(15107)
+ ..add(15108)
+ ..add(15109)
+ ..add(15110)
+ ..add(15111)
+ ..add(15112)
+ ..add(15113)
+ ..add(15114)
+ ..add(15115)
+ ..add(15116)
+ ..add(15117)
+ ..add(15118)
+ ..add(15119)
+ ..add(15120)
+ ..add(15121)
+ ..add(15122)
+ ..add(15123)
+ ..add(15124)
+ ..add(15125)
+ ..add(15126)
+ ..add(15127)
+ ..add(15128)
+ ..add(15129)
+ ..add(15130)
+ ..add(15131)
+ ..add(15132)
+ ..add(15133)
+ ..add(15134)
+ ..add(15135)
+ ..add(15136)
+ ..add(15137)
+ ..add(15138)
+ ..add(15139)
+ ..add(15140)
+ ..add(15141)
+ ..add(15142)
+ ..add(15143)
+ ..add(15144)
+ ..add(15145)
+ ..add(15146)
+ ..add(15147)
+ ..add(15148)
+ ..add(15149)
+ ..add(15150)
+ ..add(15151)
+ ..add(15152)
+ ..add(15153)
+ ..add(15154)
+ ..add(15155)
+ ..add(15156)
+ ..add(15157)
+ ..add(15158)
+ ..add(15159)
+ ..add(15160)
+ ..add(15161)
+ ..add(15162)
+ ..add(15163)
+ ..add(15164)
+ ..add(15165)
+ ..add(15166)
+ ..add(15167)
+ ..add(15168)
+ ..add(15169)
+ ..add(15170)
+ ..add(15171)
+ ..add(15172)
+ ..add(15173)
+ ..add(15174)
+ ..add(15175)
+ ..add(15176)
+ ..add(15177)
+ ..add(15178)
+ ..add(15179)
+ ..add(15180)
+ ..add(15181)
+ ..add(15182)
+ ..add(15183)
+ ..add(15184)
+ ..add(15185)
+ ..add(15186)
+ ..add(15187)
+ ..add(15188)
+ ..add(15189)
+ ..add(15190)
+ ..add(15191)
+ ..add(15192)
+ ..add(15193)
+ ..add(15194)
+ ..add(15195)
+ ..add(15196)
+ ..add(15197)
+ ..add(15198)
+ ..add(15199)
+ ..add(15200)
+ ..add(15201)
+ ..add(15202)
+ ..add(15203)
+ ..add(15204)
+ ..add(15205)
+ ..add(15206)
+ ..add(15207)
+ ..add(15208)
+ ..add(15209)
+ ..add(15210)
+ ..add(15211)
+ ..add(15212)
+ ..add(15213)
+ ..add(15214)
+ ..add(15215)
+ ..add(15216)
+ ..add(15217)
+ ..add(15218)
+ ..add(15219)
+ ..add(15220)
+ ..add(15221)
+ ..add(15222)
+ ..add(15223)
+ ..add(15224)
+ ..add(15225)
+ ..add(15226)
+ ..add(15227)
+ ..add(15228)
+ ..add(15229)
+ ..add(15230)
+ ..add(15231)
+ ..add(15232)
+ ..add(15233)
+ ..add(15234)
+ ..add(15235)
+ ..add(15236)
+ ..add(15237)
+ ..add(15238)
+ ..add(15239)
+ ..add(15240)
+ ..add(15241)
+ ..add(15242)
+ ..add(15243)
+ ..add(15244)
+ ..add(15245)
+ ..add(15246)
+ ..add(15247)
+ ..add(15248)
+ ..add(15249)
+ ..add(15250)
+ ..add(15251)
+ ..add(15252)
+ ..add(15253)
+ ..add(15254)
+ ..add(15255)
+ ..add(15256)
+ ..add(15257)
+ ..add(15258)
+ ..add(15259)
+ ..add(15260)
+ ..add(15261)
+ ..add(15262)
+ ..add(15263)
+ ..add(15264)
+ ..add(15265)
+ ..add(15266)
+ ..add(15267)
+ ..add(15268)
+ ..add(15269)
+ ..add(15270)
+ ..add(15271)
+ ..add(15272)
+ ..add(15273)
+ ..add(15274)
+ ..add(15275)
+ ..add(15276)
+ ..add(15277)
+ ..add(15278)
+ ..add(15279)
+ ..add(15280)
+ ..add(15281)
+ ..add(15282)
+ ..add(15283)
+ ..add(15284)
+ ..add(15285)
+ ..add(15286)
+ ..add(15287)
+ ..add(15288)
+ ..add(15289)
+ ..add(15290)
+ ..add(15291)
+ ..add(15292)
+ ..add(15293)
+ ..add(15294)
+ ..add(15295)
+ ..add(15296)
+ ..add(15297)
+ ..add(15298)
+ ..add(15299)
+ ..add(15300)
+ ..add(15301)
+ ..add(15302)
+ ..add(15303)
+ ..add(15304)
+ ..add(15305)
+ ..add(15306)
+ ..add(15307)
+ ..add(15308)
+ ..add(15309)
+ ..add(15310)
+ ..add(15311)
+ ..add(15312)
+ ..add(15313)
+ ..add(15314)
+ ..add(15315)
+ ..add(15316)
+ ..add(15317)
+ ..add(15318)
+ ..add(15319)
+ ..add(15320)
+ ..add(15321)
+ ..add(15322)
+ ..add(15323)
+ ..add(15324)
+ ..add(15325)
+ ..add(15326)
+ ..add(15327)
+ ..add(15328)
+ ..add(15329)
+ ..add(15330)
+ ..add(15331)
+ ..add(15332)
+ ..add(15333)
+ ..add(15334)
+ ..add(15335)
+ ..add(15336)
+ ..add(15337)
+ ..add(15338)
+ ..add(15339)
+ ..add(15340)
+ ..add(15341)
+ ..add(15342)
+ ..add(15343)
+ ..add(15344)
+ ..add(15345)
+ ..add(15346)
+ ..add(15347)
+ ..add(15348)
+ ..add(15349)
+ ..add(15350)
+ ..add(15351)
+ ..add(15352)
+ ..add(15353)
+ ..add(15354)
+ ..add(15355)
+ ..add(15356)
+ ..add(15357)
+ ..add(15358)
+ ..add(15359)
+ ..add(15360)
+ ..add(15361)
+ ..add(15362)
+ ..add(15363)
+ ..add(15364)
+ ..add(15365)
+ ..add(15366)
+ ..add(15367)
+ ..add(15368)
+ ..add(15369)
+ ..add(15370)
+ ..add(15371)
+ ..add(15372)
+ ..add(15373)
+ ..add(15374)
+ ..add(15375)
+ ..add(15376)
+ ..add(15377)
+ ..add(15378)
+ ..add(15379)
+ ..add(15380)
+ ..add(15381)
+ ..add(15382)
+ ..add(15383)
+ ..add(15384)
+ ..add(15385)
+ ..add(15386)
+ ..add(15387)
+ ..add(15388)
+ ..add(15389)
+ ..add(15390)
+ ..add(15391)
+ ..add(15392)
+ ..add(15393)
+ ..add(15394)
+ ..add(15395)
+ ..add(15396)
+ ..add(15397)
+ ..add(15398)
+ ..add(15399)
+ ..add(15400)
+ ..add(15401)
+ ..add(15402)
+ ..add(15403)
+ ..add(15404)
+ ..add(15405)
+ ..add(15406)
+ ..add(15407)
+ ..add(15408)
+ ..add(15409)
+ ..add(15410)
+ ..add(15411)
+ ..add(15412)
+ ..add(15413)
+ ..add(15414)
+ ..add(15415)
+ ..add(15416)
+ ..add(15417)
+ ..add(15418)
+ ..add(15419)
+ ..add(15420)
+ ..add(15421)
+ ..add(15422)
+ ..add(15423)
+ ..add(15424)
+ ..add(15425)
+ ..add(15426)
+ ..add(15427)
+ ..add(15428)
+ ..add(15429)
+ ..add(15430)
+ ..add(15431)
+ ..add(15432)
+ ..add(15433)
+ ..add(15434)
+ ..add(15435)
+ ..add(15436)
+ ..add(15437)
+ ..add(15438)
+ ..add(15439)
+ ..add(15440)
+ ..add(15441)
+ ..add(15442)
+ ..add(15443)
+ ..add(15444)
+ ..add(15445)
+ ..add(15446)
+ ..add(15447)
+ ..add(15448)
+ ..add(15449)
+ ..add(15450)
+ ..add(15451)
+ ..add(15452)
+ ..add(15453)
+ ..add(15454)
+ ..add(15455)
+ ..add(15456)
+ ..add(15457)
+ ..add(15458)
+ ..add(15459)
+ ..add(15460)
+ ..add(15461)
+ ..add(15462)
+ ..add(15463)
+ ..add(15464)
+ ..add(15465)
+ ..add(15466)
+ ..add(15467)
+ ..add(15468)
+ ..add(15469)
+ ..add(15470)
+ ..add(15471)
+ ..add(15472)
+ ..add(15473)
+ ..add(15474)
+ ..add(15475)
+ ..add(15476)
+ ..add(15477)
+ ..add(15478)
+ ..add(15479)
+ ..add(15480)
+ ..add(15481)
+ ..add(15482)
+ ..add(15483)
+ ..add(15484)
+ ..add(15485)
+ ..add(15486)
+ ..add(15487)
+ ..add(15488)
+ ..add(15489)
+ ..add(15490)
+ ..add(15491)
+ ..add(15492)
+ ..add(15493)
+ ..add(15494)
+ ..add(15495)
+ ..add(15496)
+ ..add(15497)
+ ..add(15498)
+ ..add(15499)
+ ..add(15500)
+ ..add(15501)
+ ..add(15502)
+ ..add(15503)
+ ..add(15504)
+ ..add(15505)
+ ..add(15506)
+ ..add(15507)
+ ..add(15508)
+ ..add(15509)
+ ..add(15510)
+ ..add(15511)
+ ..add(15512)
+ ..add(15513)
+ ..add(15514)
+ ..add(15515)
+ ..add(15516)
+ ..add(15517)
+ ..add(15518)
+ ..add(15519)
+ ..add(15520)
+ ..add(15521)
+ ..add(15522)
+ ..add(15523)
+ ..add(15524)
+ ..add(15525)
+ ..add(15526)
+ ..add(15527)
+ ..add(15528)
+ ..add(15529)
+ ..add(15530)
+ ..add(15531)
+ ..add(15532)
+ ..add(15533)
+ ..add(15534)
+ ..add(15535)
+ ..add(15536)
+ ..add(15537)
+ ..add(15538)
+ ..add(15539)
+ ..add(15540)
+ ..add(15541)
+ ..add(15542)
+ ..add(15543)
+ ..add(15544)
+ ..add(15545)
+ ..add(15546)
+ ..add(15547)
+ ..add(15548)
+ ..add(15549)
+ ..add(15550)
+ ..add(15551)
+ ..add(15552)
+ ..add(15553)
+ ..add(15554)
+ ..add(15555)
+ ..add(15556)
+ ..add(15557)
+ ..add(15558)
+ ..add(15559)
+ ..add(15560)
+ ..add(15561)
+ ..add(15562)
+ ..add(15563)
+ ..add(15564)
+ ..add(15565)
+ ..add(15566)
+ ..add(15567)
+ ..add(15568)
+ ..add(15569)
+ ..add(15570)
+ ..add(15571)
+ ..add(15572)
+ ..add(15573)
+ ..add(15574)
+ ..add(15575)
+ ..add(15576)
+ ..add(15577)
+ ..add(15578)
+ ..add(15579)
+ ..add(15580)
+ ..add(15581)
+ ..add(15582)
+ ..add(15583)
+ ..add(15584)
+ ..add(15585)
+ ..add(15586)
+ ..add(15587)
+ ..add(15588)
+ ..add(15589)
+ ..add(15590)
+ ..add(15591)
+ ..add(15592)
+ ..add(15593)
+ ..add(15594)
+ ..add(15595)
+ ..add(15596)
+ ..add(15597)
+ ..add(15598)
+ ..add(15599)
+ ..add(15600)
+ ..add(15601)
+ ..add(15602)
+ ..add(15603)
+ ..add(15604)
+ ..add(15605)
+ ..add(15606)
+ ..add(15607)
+ ..add(15608)
+ ..add(15609)
+ ..add(15610)
+ ..add(15611)
+ ..add(15612)
+ ..add(15613)
+ ..add(15614)
+ ..add(15615)
+ ..add(15616)
+ ..add(15617)
+ ..add(15618)
+ ..add(15619)
+ ..add(15620)
+ ..add(15621)
+ ..add(15622)
+ ..add(15623)
+ ..add(15624)
+ ..add(15625)
+ ..add(15626)
+ ..add(15627)
+ ..add(15628)
+ ..add(15629)
+ ..add(15630)
+ ..add(15631)
+ ..add(15632)
+ ..add(15633)
+ ..add(15634)
+ ..add(15635)
+ ..add(15636)
+ ..add(15637)
+ ..add(15638)
+ ..add(15639)
+ ..add(15640)
+ ..add(15641)
+ ..add(15642)
+ ..add(15643)
+ ..add(15644)
+ ..add(15645)
+ ..add(15646)
+ ..add(15647)
+ ..add(15648)
+ ..add(15649)
+ ..add(15650)
+ ..add(15651)
+ ..add(15652)
+ ..add(15653)
+ ..add(15654)
+ ..add(15655)
+ ..add(15656)
+ ..add(15657)
+ ..add(15658)
+ ..add(15659)
+ ..add(15660)
+ ..add(15661)
+ ..add(15662)
+ ..add(15663)
+ ..add(15664)
+ ..add(15665)
+ ..add(15666)
+ ..add(15667)
+ ..add(15668)
+ ..add(15669)
+ ..add(15670)
+ ..add(15671)
+ ..add(15672)
+ ..add(15673)
+ ..add(15674)
+ ..add(15675)
+ ..add(15676)
+ ..add(15677)
+ ..add(15678)
+ ..add(15679)
+ ..add(15680)
+ ..add(15681)
+ ..add(15682)
+ ..add(15683)
+ ..add(15684)
+ ..add(15685)
+ ..add(15686)
+ ..add(15687)
+ ..add(15688)
+ ..add(15689)
+ ..add(15690)
+ ..add(15691)
+ ..add(15692)
+ ..add(15693)
+ ..add(15694)
+ ..add(15695)
+ ..add(15696)
+ ..add(15697)
+ ..add(15698)
+ ..add(15699)
+ ..add(15700)
+ ..add(15701)
+ ..add(15702)
+ ..add(15703)
+ ..add(15704)
+ ..add(15705)
+ ..add(15706)
+ ..add(15707)
+ ..add(15708)
+ ..add(15709)
+ ..add(15710)
+ ..add(15711)
+ ..add(15712)
+ ..add(15713)
+ ..add(15714)
+ ..add(15715)
+ ..add(15716)
+ ..add(15717)
+ ..add(15718)
+ ..add(15719)
+ ..add(15720)
+ ..add(15721)
+ ..add(15722)
+ ..add(15723)
+ ..add(15724)
+ ..add(15725)
+ ..add(15726)
+ ..add(15727)
+ ..add(15728)
+ ..add(15729)
+ ..add(15730)
+ ..add(15731)
+ ..add(15732)
+ ..add(15733)
+ ..add(15734)
+ ..add(15735)
+ ..add(15736)
+ ..add(15737)
+ ..add(15738)
+ ..add(15739)
+ ..add(15740)
+ ..add(15741)
+ ..add(15742)
+ ..add(15743)
+ ..add(15744)
+ ..add(15745)
+ ..add(15746)
+ ..add(15747)
+ ..add(15748)
+ ..add(15749)
+ ..add(15750)
+ ..add(15751)
+ ..add(15752)
+ ..add(15753)
+ ..add(15754)
+ ..add(15755)
+ ..add(15756)
+ ..add(15757)
+ ..add(15758)
+ ..add(15759)
+ ..add(15760)
+ ..add(15761)
+ ..add(15762)
+ ..add(15763)
+ ..add(15764)
+ ..add(15765)
+ ..add(15766)
+ ..add(15767)
+ ..add(15768)
+ ..add(15769)
+ ..add(15770)
+ ..add(15771)
+ ..add(15772)
+ ..add(15773)
+ ..add(15774)
+ ..add(15775)
+ ..add(15776)
+ ..add(15777)
+ ..add(15778)
+ ..add(15779)
+ ..add(15780)
+ ..add(15781)
+ ..add(15782)
+ ..add(15783)
+ ..add(15784)
+ ..add(15785)
+ ..add(15786)
+ ..add(15787)
+ ..add(15788)
+ ..add(15789)
+ ..add(15790)
+ ..add(15791)
+ ..add(15792)
+ ..add(15793)
+ ..add(15794)
+ ..add(15795)
+ ..add(15796)
+ ..add(15797)
+ ..add(15798)
+ ..add(15799)
+ ..add(15800)
+ ..add(15801)
+ ..add(15802)
+ ..add(15803)
+ ..add(15804)
+ ..add(15805)
+ ..add(15806)
+ ..add(15807)
+ ..add(15808)
+ ..add(15809)
+ ..add(15810)
+ ..add(15811)
+ ..add(15812)
+ ..add(15813)
+ ..add(15814)
+ ..add(15815)
+ ..add(15816)
+ ..add(15817)
+ ..add(15818)
+ ..add(15819)
+ ..add(15820)
+ ..add(15821)
+ ..add(15822)
+ ..add(15823)
+ ..add(15824)
+ ..add(15825)
+ ..add(15826)
+ ..add(15827)
+ ..add(15828)
+ ..add(15829)
+ ..add(15830)
+ ..add(15831)
+ ..add(15832)
+ ..add(15833)
+ ..add(15834)
+ ..add(15835)
+ ..add(15836)
+ ..add(15837)
+ ..add(15838)
+ ..add(15839)
+ ..add(15840)
+ ..add(15841)
+ ..add(15842)
+ ..add(15843)
+ ..add(15844)
+ ..add(15845)
+ ..add(15846)
+ ..add(15847)
+ ..add(15848)
+ ..add(15849)
+ ..add(15850)
+ ..add(15851)
+ ..add(15852)
+ ..add(15853)
+ ..add(15854)
+ ..add(15855)
+ ..add(15856)
+ ..add(15857)
+ ..add(15858)
+ ..add(15859)
+ ..add(15860)
+ ..add(15861)
+ ..add(15862)
+ ..add(15863)
+ ..add(15864)
+ ..add(15865)
+ ..add(15866)
+ ..add(15867)
+ ..add(15868)
+ ..add(15869)
+ ..add(15870)
+ ..add(15871)
+ ..add(15872)
+ ..add(15873)
+ ..add(15874)
+ ..add(15875)
+ ..add(15876)
+ ..add(15877)
+ ..add(15878)
+ ..add(15879)
+ ..add(15880)
+ ..add(15881)
+ ..add(15882)
+ ..add(15883)
+ ..add(15884)
+ ..add(15885)
+ ..add(15886)
+ ..add(15887)
+ ..add(15888)
+ ..add(15889)
+ ..add(15890)
+ ..add(15891)
+ ..add(15892)
+ ..add(15893)
+ ..add(15894)
+ ..add(15895)
+ ..add(15896)
+ ..add(15897)
+ ..add(15898)
+ ..add(15899)
+ ..add(15900)
+ ..add(15901)
+ ..add(15902)
+ ..add(15903)
+ ..add(15904)
+ ..add(15905)
+ ..add(15906)
+ ..add(15907)
+ ..add(15908)
+ ..add(15909)
+ ..add(15910)
+ ..add(15911)
+ ..add(15912)
+ ..add(15913)
+ ..add(15914)
+ ..add(15915)
+ ..add(15916)
+ ..add(15917)
+ ..add(15918)
+ ..add(15919)
+ ..add(15920)
+ ..add(15921)
+ ..add(15922)
+ ..add(15923)
+ ..add(15924)
+ ..add(15925)
+ ..add(15926)
+ ..add(15927)
+ ..add(15928)
+ ..add(15929)
+ ..add(15930)
+ ..add(15931)
+ ..add(15932)
+ ..add(15933)
+ ..add(15934)
+ ..add(15935)
+ ..add(15936)
+ ..add(15937)
+ ..add(15938)
+ ..add(15939)
+ ..add(15940)
+ ..add(15941)
+ ..add(15942)
+ ..add(15943)
+ ..add(15944)
+ ..add(15945)
+ ..add(15946)
+ ..add(15947)
+ ..add(15948)
+ ..add(15949)
+ ..add(15950)
+ ..add(15951)
+ ..add(15952)
+ ..add(15953)
+ ..add(15954)
+ ..add(15955)
+ ..add(15956)
+ ..add(15957)
+ ..add(15958)
+ ..add(15959)
+ ..add(15960)
+ ..add(15961)
+ ..add(15962)
+ ..add(15963)
+ ..add(15964)
+ ..add(15965)
+ ..add(15966)
+ ..add(15967)
+ ..add(15968)
+ ..add(15969)
+ ..add(15970)
+ ..add(15971)
+ ..add(15972)
+ ..add(15973)
+ ..add(15974)
+ ..add(15975)
+ ..add(15976)
+ ..add(15977)
+ ..add(15978)
+ ..add(15979)
+ ..add(15980)
+ ..add(15981)
+ ..add(15982)
+ ..add(15983)
+ ..add(15984)
+ ..add(15985)
+ ..add(15986)
+ ..add(15987)
+ ..add(15988)
+ ..add(15989)
+ ..add(15990)
+ ..add(15991)
+ ..add(15992)
+ ..add(15993)
+ ..add(15994)
+ ..add(15995)
+ ..add(15996)
+ ..add(15997)
+ ..add(15998)
+ ..add(15999)
+ ..add(16000)
+ ..add(16001)
+ ..add(16002)
+ ..add(16003)
+ ..add(16004)
+ ..add(16005)
+ ..add(16006)
+ ..add(16007)
+ ..add(16008)
+ ..add(16009)
+ ..add(16010)
+ ..add(16011)
+ ..add(16012)
+ ..add(16013)
+ ..add(16014)
+ ..add(16015)
+ ..add(16016)
+ ..add(16017)
+ ..add(16018)
+ ..add(16019)
+ ..add(16020)
+ ..add(16021)
+ ..add(16022)
+ ..add(16023)
+ ..add(16024)
+ ..add(16025)
+ ..add(16026)
+ ..add(16027)
+ ..add(16028)
+ ..add(16029)
+ ..add(16030)
+ ..add(16031)
+ ..add(16032)
+ ..add(16033)
+ ..add(16034)
+ ..add(16035)
+ ..add(16036)
+ ..add(16037)
+ ..add(16038)
+ ..add(16039)
+ ..add(16040)
+ ..add(16041)
+ ..add(16042)
+ ..add(16043)
+ ..add(16044)
+ ..add(16045)
+ ..add(16046)
+ ..add(16047)
+ ..add(16048)
+ ..add(16049)
+ ..add(16050)
+ ..add(16051)
+ ..add(16052)
+ ..add(16053)
+ ..add(16054)
+ ..add(16055)
+ ..add(16056)
+ ..add(16057)
+ ..add(16058)
+ ..add(16059)
+ ..add(16060)
+ ..add(16061)
+ ..add(16062)
+ ..add(16063)
+ ..add(16064)
+ ..add(16065)
+ ..add(16066)
+ ..add(16067)
+ ..add(16068)
+ ..add(16069)
+ ..add(16070)
+ ..add(16071)
+ ..add(16072)
+ ..add(16073)
+ ..add(16074)
+ ..add(16075)
+ ..add(16076)
+ ..add(16077)
+ ..add(16078)
+ ..add(16079)
+ ..add(16080)
+ ..add(16081)
+ ..add(16082)
+ ..add(16083)
+ ..add(16084)
+ ..add(16085)
+ ..add(16086)
+ ..add(16087)
+ ..add(16088)
+ ..add(16089)
+ ..add(16090)
+ ..add(16091)
+ ..add(16092)
+ ..add(16093)
+ ..add(16094)
+ ..add(16095)
+ ..add(16096)
+ ..add(16097)
+ ..add(16098)
+ ..add(16099)
+ ..add(16100)
+ ..add(16101)
+ ..add(16102)
+ ..add(16103)
+ ..add(16104)
+ ..add(16105)
+ ..add(16106)
+ ..add(16107)
+ ..add(16108)
+ ..add(16109)
+ ..add(16110)
+ ..add(16111)
+ ..add(16112)
+ ..add(16113)
+ ..add(16114)
+ ..add(16115)
+ ..add(16116)
+ ..add(16117)
+ ..add(16118)
+ ..add(16119)
+ ..add(16120)
+ ..add(16121)
+ ..add(16122)
+ ..add(16123)
+ ..add(16124)
+ ..add(16125)
+ ..add(16126)
+ ..add(16127)
+ ..add(16128)
+ ..add(16129)
+ ..add(16130)
+ ..add(16131)
+ ..add(16132)
+ ..add(16133)
+ ..add(16134)
+ ..add(16135)
+ ..add(16136)
+ ..add(16137)
+ ..add(16138)
+ ..add(16139)
+ ..add(16140)
+ ..add(16141)
+ ..add(16142)
+ ..add(16143)
+ ..add(16144)
+ ..add(16145)
+ ..add(16146)
+ ..add(16147)
+ ..add(16148)
+ ..add(16149)
+ ..add(16150)
+ ..add(16151)
+ ..add(16152)
+ ..add(16153)
+ ..add(16154)
+ ..add(16155)
+ ..add(16156)
+ ..add(16157)
+ ..add(16158)
+ ..add(16159)
+ ..add(16160)
+ ..add(16161)
+ ..add(16162)
+ ..add(16163)
+ ..add(16164)
+ ..add(16165)
+ ..add(16166)
+ ..add(16167)
+ ..add(16168)
+ ..add(16169)
+ ..add(16170)
+ ..add(16171)
+ ..add(16172)
+ ..add(16173)
+ ..add(16174)
+ ..add(16175)
+ ..add(16176)
+ ..add(16177)
+ ..add(16178)
+ ..add(16179)
+ ..add(16180)
+ ..add(16181)
+ ..add(16182)
+ ..add(16183)
+ ..add(16184)
+ ..add(16185)
+ ..add(16186)
+ ..add(16187)
+ ..add(16188)
+ ..add(16189)
+ ..add(16190)
+ ..add(16191)
+ ..add(16192)
+ ..add(16193)
+ ..add(16194)
+ ..add(16195)
+ ..add(16196)
+ ..add(16197)
+ ..add(16198)
+ ..add(16199)
+ ..add(16200)
+ ..add(16201)
+ ..add(16202)
+ ..add(16203)
+ ..add(16204)
+ ..add(16205)
+ ..add(16206)
+ ..add(16207)
+ ..add(16208)
+ ..add(16209)
+ ..add(16210)
+ ..add(16211)
+ ..add(16212)
+ ..add(16213)
+ ..add(16214)
+ ..add(16215)
+ ..add(16216)
+ ..add(16217)
+ ..add(16218)
+ ..add(16219)
+ ..add(16220)
+ ..add(16221)
+ ..add(16222)
+ ..add(16223)
+ ..add(16224)
+ ..add(16225)
+ ..add(16226)
+ ..add(16227)
+ ..add(16228)
+ ..add(16229)
+ ..add(16230)
+ ..add(16231)
+ ..add(16232)
+ ..add(16233)
+ ..add(16234)
+ ..add(16235)
+ ..add(16236)
+ ..add(16237)
+ ..add(16238)
+ ..add(16239)
+ ..add(16240)
+ ..add(16241)
+ ..add(16242)
+ ..add(16243)
+ ..add(16244)
+ ..add(16245)
+ ..add(16246)
+ ..add(16247)
+ ..add(16248)
+ ..add(16249)
+ ..add(16250)
+ ..add(16251)
+ ..add(16252)
+ ..add(16253)
+ ..add(16254)
+ ..add(16255)
+ ..add(16256)
+ ..add(16257)
+ ..add(16258)
+ ..add(16259)
+ ..add(16260)
+ ..add(16261)
+ ..add(16262)
+ ..add(16263)
+ ..add(16264)
+ ..add(16265)
+ ..add(16266)
+ ..add(16267)
+ ..add(16268)
+ ..add(16269)
+ ..add(16270)
+ ..add(16271)
+ ..add(16272)
+ ..add(16273)
+ ..add(16274)
+ ..add(16275)
+ ..add(16276)
+ ..add(16277)
+ ..add(16278)
+ ..add(16279)
+ ..add(16280)
+ ..add(16281)
+ ..add(16282)
+ ..add(16283)
+ ..add(16284)
+ ..add(16285)
+ ..add(16286)
+ ..add(16287)
+ ..add(16288)
+ ..add(16289)
+ ..add(16290)
+ ..add(16291)
+ ..add(16292)
+ ..add(16293)
+ ..add(16294)
+ ..add(16295)
+ ..add(16296)
+ ..add(16297)
+ ..add(16298)
+ ..add(16299)
+ ..add(16300)
+ ..add(16301)
+ ..add(16302)
+ ..add(16303)
+ ..add(16304)
+ ..add(16305)
+ ..add(16306)
+ ..add(16307)
+ ..add(16308)
+ ..add(16309)
+ ..add(16310)
+ ..add(16311)
+ ..add(16312)
+ ..add(16313)
+ ..add(16314)
+ ..add(16315)
+ ..add(16316)
+ ..add(16317)
+ ..add(16318)
+ ..add(16319)
+ ..add(16320)
+ ..add(16321)
+ ..add(16322)
+ ..add(16323)
+ ..add(16324)
+ ..add(16325)
+ ..add(16326)
+ ..add(16327)
+ ..add(16328)
+ ..add(16329)
+ ..add(16330)
+ ..add(16331)
+ ..add(16332)
+ ..add(16333)
+ ..add(16334)
+ ..add(16335)
+ ..add(16336)
+ ..add(16337)
+ ..add(16338)
+ ..add(16339)
+ ..add(16340)
+ ..add(16341)
+ ..add(16342)
+ ..add(16343)
+ ..add(16344)
+ ..add(16345)
+ ..add(16346)
+ ..add(16347)
+ ..add(16348)
+ ..add(16349)
+ ..add(16350)
+ ..add(16351)
+ ..add(16352)
+ ..add(16353)
+ ..add(16354)
+ ..add(16355)
+ ..add(16356)
+ ..add(16357)
+ ..add(16358)
+ ..add(16359)
+ ..add(16360)
+ ..add(16361)
+ ..add(16362)
+ ..add(16363)
+ ..add(16364)
+ ..add(16365)
+ ..add(16366)
+ ..add(16367)
+ ..add(16368)
+ ..add(16369)
+ ..add(16370)
+ ..add(16371)
+ ..add(16372)
+ ..add(16373)
+ ..add(16374)
+ ..add(16375)
+ ..add(16376)
+ ..add(16377)
+ ..add(16378)
+ ..add(16379)
+ ..add(16380)
+ ..add(16381)
+ ..add(16382)
+ ..add(16383)
+ ..add(16384)
+ ..add(16385)
+ ..add(16386)
+ ..add(16387)
+ ..add(16388)
+ ..add(16389)
+ ..add(16390)
+ ..add(16391)
+ ..add(16392)
+ ..add(16393)
+ ..add(16394)
+ ..add(16395)
+ ..add(16396)
+ ..add(16397)
+ ..add(16398)
+ ..add(16399)
+ ..add(16400)
+ ..add(16401)
+ ..add(16402)
+ ..add(16403)
+ ..add(16404)
+ ..add(16405)
+ ..add(16406)
+ ..add(16407)
+ ..add(16408)
+ ..add(16409)
+ ..add(16410)
+ ..add(16411)
+ ..add(16412)
+ ..add(16413)
+ ..add(16414)
+ ..add(16415)
+ ..add(16416)
+ ..add(16417)
+ ..add(16418)
+ ..add(16419)
+ ..add(16420)
+ ..add(16421)
+ ..add(16422)
+ ..add(16423)
+ ..add(16424)
+ ..add(16425)
+ ..add(16426)
+ ..add(16427)
+ ..add(16428)
+ ..add(16429)
+ ..add(16430)
+ ..add(16431)
+ ..add(16432)
+ ..add(16433)
+ ..add(16434)
+ ..add(16435)
+ ..add(16436)
+ ..add(16437)
+ ..add(16438)
+ ..add(16439)
+ ..add(16440)
+ ..add(16441)
+ ..add(16442)
+ ..add(16443)
+ ..add(16444)
+ ..add(16445)
+ ..add(16446)
+ ..add(16447)
+ ..add(16448)
+ ..add(16449)
+ ..add(16450)
+ ..add(16451)
+ ..add(16452)
+ ..add(16453)
+ ..add(16454)
+ ..add(16455)
+ ..add(16456)
+ ..add(16457)
+ ..add(16458)
+ ..add(16459)
+ ..add(16460)
+ ..add(16461)
+ ..add(16462)
+ ..add(16463)
+ ..add(16464)
+ ..add(16465)
+ ..add(16466)
+ ..add(16467)
+ ..add(16468)
+ ..add(16469)
+ ..add(16470)
+ ..add(16471)
+ ..add(16472)
+ ..add(16473)
+ ..add(16474)
+ ..add(16475)
+ ..add(16476)
+ ..add(16477)
+ ..add(16478)
+ ..add(16479)
+ ..add(16480)
+ ..add(16481)
+ ..add(16482)
+ ..add(16483)
+ ..add(16484)
+ ..add(16485)
+ ..add(16486)
+ ..add(16487)
+ ..add(16488)
+ ..add(16489)
+ ..add(16490)
+ ..add(16491)
+ ..add(16492)
+ ..add(16493)
+ ..add(16494)
+ ..add(16495)
+ ..add(16496)
+ ..add(16497)
+ ..add(16498)
+ ..add(16499)
+ ..add(16500)
+ ..add(16501)
+ ..add(16502)
+ ..add(16503)
+ ..add(16504)
+ ..add(16505)
+ ..add(16506)
+ ..add(16507)
+ ..add(16508)
+ ..add(16509)
+ ..add(16510)
+ ..add(16511)
+ ..add(16512)
+ ..add(16513)
+ ..add(16514)
+ ..add(16515)
+ ..add(16516)
+ ..add(16517)
+ ..add(16518)
+ ..add(16519)
+ ..add(16520)
+ ..add(16521)
+ ..add(16522)
+ ..add(16523)
+ ..add(16524)
+ ..add(16525)
+ ..add(16526)
+ ..add(16527)
+ ..add(16528)
+ ..add(16529)
+ ..add(16530)
+ ..add(16531)
+ ..add(16532)
+ ..add(16533)
+ ..add(16534)
+ ..add(16535)
+ ..add(16536)
+ ..add(16537)
+ ..add(16538)
+ ..add(16539)
+ ..add(16540)
+ ..add(16541)
+ ..add(16542)
+ ..add(16543)
+ ..add(16544)
+ ..add(16545)
+ ..add(16546)
+ ..add(16547)
+ ..add(16548)
+ ..add(16549)
+ ..add(16550)
+ ..add(16551)
+ ..add(16552)
+ ..add(16553)
+ ..add(16554)
+ ..add(16555)
+ ..add(16556)
+ ..add(16557)
+ ..add(16558)
+ ..add(16559)
+ ..add(16560)
+ ..add(16561)
+ ..add(16562)
+ ..add(16563)
+ ..add(16564)
+ ..add(16565)
+ ..add(16566)
+ ..add(16567)
+ ..add(16568)
+ ..add(16569)
+ ..add(16570)
+ ..add(16571)
+ ..add(16572)
+ ..add(16573)
+ ..add(16574)
+ ..add(16575)
+ ..add(16576)
+ ..add(16577)
+ ..add(16578)
+ ..add(16579)
+ ..add(16580)
+ ..add(16581)
+ ..add(16582)
+ ..add(16583)
+ ..add(16584)
+ ..add(16585)
+ ..add(16586)
+ ..add(16587)
+ ..add(16588)
+ ..add(16589)
+ ..add(16590)
+ ..add(16591)
+ ..add(16592)
+ ..add(16593)
+ ..add(16594)
+ ..add(16595)
+ ..add(16596)
+ ..add(16597)
+ ..add(16598)
+ ..add(16599)
+ ..add(16600)
+ ..add(16601)
+ ..add(16602)
+ ..add(16603)
+ ..add(16604)
+ ..add(16605)
+ ..add(16606)
+ ..add(16607)
+ ..add(16608)
+ ..add(16609)
+ ..add(16610)
+ ..add(16611)
+ ..add(16612)
+ ..add(16613)
+ ..add(16614)
+ ..add(16615)
+ ..add(16616)
+ ..add(16617)
+ ..add(16618)
+ ..add(16619)
+ ..add(16620)
+ ..add(16621)
+ ..add(16622)
+ ..add(16623)
+ ..add(16624)
+ ..add(16625)
+ ..add(16626)
+ ..add(16627)
+ ..add(16628)
+ ..add(16629)
+ ..add(16630)
+ ..add(16631)
+ ..add(16632)
+ ..add(16633)
+ ..add(16634)
+ ..add(16635)
+ ..add(16636)
+ ..add(16637)
+ ..add(16638)
+ ..add(16639)
+ ..add(16640)
+ ..add(16641)
+ ..add(16642)
+ ..add(16643)
+ ..add(16644)
+ ..add(16645)
+ ..add(16646)
+ ..add(16647)
+ ..add(16648)
+ ..add(16649)
+ ..add(16650)
+ ..add(16651)
+ ..add(16652)
+ ..add(16653)
+ ..add(16654)
+ ..add(16655)
+ ..add(16656)
+ ..add(16657)
+ ..add(16658)
+ ..add(16659)
+ ..add(16660)
+ ..add(16661)
+ ..add(16662)
+ ..add(16663)
+ ..add(16664)
+ ..add(16665)
+ ..add(16666)
+ ..add(16667)
+ ..add(16668)
+ ..add(16669)
+ ..add(16670)
+ ..add(16671)
+ ..add(16672)
+ ..add(16673)
+ ..add(16674)
+ ..add(16675)
+ ..add(16676)
+ ..add(16677)
+ ..add(16678)
+ ..add(16679)
+ ..add(16680)
+ ..add(16681)
+ ..add(16682)
+ ..add(16683)
+ ..add(16684)
+ ..add(16685)
+ ..add(16686)
+ ..add(16687)
+ ..add(16688)
+ ..add(16689)
+ ..add(16690)
+ ..add(16691)
+ ..add(16692)
+ ..add(16693)
+ ..add(16694)
+ ..add(16695)
+ ..add(16696)
+ ..add(16697)
+ ..add(16698)
+ ..add(16699)
+ ..add(16700)
+ ..add(16701)
+ ..add(16702)
+ ..add(16703)
+ ..add(16704)
+ ..add(16705)
+ ..add(16706)
+ ..add(16707)
+ ..add(16708)
+ ..add(16709)
+ ..add(16710)
+ ..add(16711)
+ ..add(16712)
+ ..add(16713)
+ ..add(16714)
+ ..add(16715)
+ ..add(16716)
+ ..add(16717)
+ ..add(16718)
+ ..add(16719)
+ ..add(16720)
+ ..add(16721)
+ ..add(16722)
+ ..add(16723)
+ ..add(16724)
+ ..add(16725)
+ ..add(16726)
+ ..add(16727)
+ ..add(16728)
+ ..add(16729)
+ ..add(16730)
+ ..add(16731)
+ ..add(16732)
+ ..add(16733)
+ ..add(16734)
+ ..add(16735)
+ ..add(16736)
+ ..add(16737)
+ ..add(16738)
+ ..add(16739)
+ ..add(16740)
+ ..add(16741)
+ ..add(16742)
+ ..add(16743)
+ ..add(16744)
+ ..add(16745)
+ ..add(16746)
+ ..add(16747)
+ ..add(16748)
+ ..add(16749)
+ ..add(16750)
+ ..add(16751)
+ ..add(16752)
+ ..add(16753)
+ ..add(16754)
+ ..add(16755)
+ ..add(16756)
+ ..add(16757)
+ ..add(16758)
+ ..add(16759)
+ ..add(16760)
+ ..add(16761)
+ ..add(16762)
+ ..add(16763)
+ ..add(16764)
+ ..add(16765)
+ ..add(16766)
+ ..add(16767)
+ ..add(16768)
+ ..add(16769)
+ ..add(16770)
+ ..add(16771)
+ ..add(16772)
+ ..add(16773)
+ ..add(16774)
+ ..add(16775)
+ ..add(16776)
+ ..add(16777)
+ ..add(16778)
+ ..add(16779)
+ ..add(16780)
+ ..add(16781)
+ ..add(16782)
+ ..add(16783)
+ ..add(16784)
+ ..add(16785)
+ ..add(16786)
+ ..add(16787)
+ ..add(16788)
+ ..add(16789)
+ ..add(16790)
+ ..add(16791)
+ ..add(16792)
+ ..add(16793)
+ ..add(16794)
+ ..add(16795)
+ ..add(16796)
+ ..add(16797)
+ ..add(16798)
+ ..add(16799)
+ ..add(16800)
+ ..add(16801)
+ ..add(16802)
+ ..add(16803)
+ ..add(16804)
+ ..add(16805)
+ ..add(16806)
+ ..add(16807)
+ ..add(16808)
+ ..add(16809)
+ ..add(16810)
+ ..add(16811)
+ ..add(16812)
+ ..add(16813)
+ ..add(16814)
+ ..add(16815)
+ ..add(16816)
+ ..add(16817)
+ ..add(16818)
+ ..add(16819)
+ ..add(16820)
+ ..add(16821)
+ ..add(16822)
+ ..add(16823)
+ ..add(16824)
+ ..add(16825)
+ ..add(16826)
+ ..add(16827)
+ ..add(16828)
+ ..add(16829)
+ ..add(16830)
+ ..add(16831)
+ ..add(16832)
+ ..add(16833)
+ ..add(16834)
+ ..add(16835)
+ ..add(16836)
+ ..add(16837)
+ ..add(16838)
+ ..add(16839)
+ ..add(16840)
+ ..add(16841)
+ ..add(16842)
+ ..add(16843)
+ ..add(16844)
+ ..add(16845)
+ ..add(16846)
+ ..add(16847)
+ ..add(16848)
+ ..add(16849)
+ ..add(16850)
+ ..add(16851)
+ ..add(16852)
+ ..add(16853)
+ ..add(16854)
+ ..add(16855)
+ ..add(16856)
+ ..add(16857)
+ ..add(16858)
+ ..add(16859)
+ ..add(16860)
+ ..add(16861)
+ ..add(16862)
+ ..add(16863)
+ ..add(16864)
+ ..add(16865)
+ ..add(16866)
+ ..add(16867)
+ ..add(16868)
+ ..add(16869)
+ ..add(16870)
+ ..add(16871)
+ ..add(16872)
+ ..add(16873)
+ ..add(16874)
+ ..add(16875)
+ ..add(16876)
+ ..add(16877)
+ ..add(16878)
+ ..add(16879)
+ ..add(16880)
+ ..add(16881)
+ ..add(16882)
+ ..add(16883)
+ ..add(16884)
+ ..add(16885)
+ ..add(16886)
+ ..add(16887)
+ ..add(16888)
+ ..add(16889)
+ ..add(16890)
+ ..add(16891)
+ ..add(16892)
+ ..add(16893)
+ ..add(16894)
+ ..add(16895)
+ ..add(16896)
+ ..add(16897)
+ ..add(16898)
+ ..add(16899)
+ ..add(16900)
+ ..add(16901)
+ ..add(16902)
+ ..add(16903)
+ ..add(16904)
+ ..add(16905)
+ ..add(16906)
+ ..add(16907)
+ ..add(16908)
+ ..add(16909)
+ ..add(16910)
+ ..add(16911)
+ ..add(16912)
+ ..add(16913)
+ ..add(16914)
+ ..add(16915)
+ ..add(16916)
+ ..add(16917)
+ ..add(16918)
+ ..add(16919)
+ ..add(16920)
+ ..add(16921)
+ ..add(16922)
+ ..add(16923)
+ ..add(16924)
+ ..add(16925)
+ ..add(16926)
+ ..add(16927)
+ ..add(16928)
+ ..add(16929)
+ ..add(16930)
+ ..add(16931)
+ ..add(16932)
+ ..add(16933)
+ ..add(16934)
+ ..add(16935)
+ ..add(16936)
+ ..add(16937)
+ ..add(16938)
+ ..add(16939)
+ ..add(16940)
+ ..add(16941)
+ ..add(16942)
+ ..add(16943)
+ ..add(16944)
+ ..add(16945)
+ ..add(16946)
+ ..add(16947)
+ ..add(16948)
+ ..add(16949)
+ ..add(16950)
+ ..add(16951)
+ ..add(16952)
+ ..add(16953)
+ ..add(16954)
+ ..add(16955)
+ ..add(16956)
+ ..add(16957)
+ ..add(16958)
+ ..add(16959)
+ ..add(16960)
+ ..add(16961)
+ ..add(16962)
+ ..add(16963)
+ ..add(16964)
+ ..add(16965)
+ ..add(16966)
+ ..add(16967)
+ ..add(16968)
+ ..add(16969)
+ ..add(16970)
+ ..add(16971)
+ ..add(16972)
+ ..add(16973)
+ ..add(16974)
+ ..add(16975)
+ ..add(16976)
+ ..add(16977)
+ ..add(16978)
+ ..add(16979)
+ ..add(16980)
+ ..add(16981)
+ ..add(16982)
+ ..add(16983)
+ ..add(16984)
+ ..add(16985)
+ ..add(16986)
+ ..add(16987)
+ ..add(16988)
+ ..add(16989)
+ ..add(16990)
+ ..add(16991)
+ ..add(16992)
+ ..add(16993)
+ ..add(16994)
+ ..add(16995)
+ ..add(16996)
+ ..add(16997)
+ ..add(16998)
+ ..add(16999)
+ ..add(17000)
+ ..add(17001)
+ ..add(17002)
+ ..add(17003)
+ ..add(17004)
+ ..add(17005)
+ ..add(17006)
+ ..add(17007)
+ ..add(17008)
+ ..add(17009)
+ ..add(17010)
+ ..add(17011)
+ ..add(17012)
+ ..add(17013)
+ ..add(17014)
+ ..add(17015)
+ ..add(17016)
+ ..add(17017)
+ ..add(17018)
+ ..add(17019)
+ ..add(17020)
+ ..add(17021)
+ ..add(17022)
+ ..add(17023)
+ ..add(17024)
+ ..add(17025)
+ ..add(17026)
+ ..add(17027)
+ ..add(17028)
+ ..add(17029)
+ ..add(17030)
+ ..add(17031)
+ ..add(17032)
+ ..add(17033)
+ ..add(17034)
+ ..add(17035)
+ ..add(17036)
+ ..add(17037)
+ ..add(17038)
+ ..add(17039)
+ ..add(17040)
+ ..add(17041)
+ ..add(17042)
+ ..add(17043)
+ ..add(17044)
+ ..add(17045)
+ ..add(17046)
+ ..add(17047)
+ ..add(17048)
+ ..add(17049)
+ ..add(17050)
+ ..add(17051)
+ ..add(17052)
+ ..add(17053)
+ ..add(17054)
+ ..add(17055)
+ ..add(17056)
+ ..add(17057)
+ ..add(17058)
+ ..add(17059)
+ ..add(17060)
+ ..add(17061)
+ ..add(17062)
+ ..add(17063)
+ ..add(17064)
+ ..add(17065)
+ ..add(17066)
+ ..add(17067)
+ ..add(17068)
+ ..add(17069)
+ ..add(17070)
+ ..add(17071)
+ ..add(17072)
+ ..add(17073)
+ ..add(17074)
+ ..add(17075)
+ ..add(17076)
+ ..add(17077)
+ ..add(17078)
+ ..add(17079)
+ ..add(17080)
+ ..add(17081)
+ ..add(17082)
+ ..add(17083)
+ ..add(17084)
+ ..add(17085)
+ ..add(17086)
+ ..add(17087)
+ ..add(17088)
+ ..add(17089)
+ ..add(17090)
+ ..add(17091)
+ ..add(17092)
+ ..add(17093)
+ ..add(17094)
+ ..add(17095)
+ ..add(17096)
+ ..add(17097)
+ ..add(17098)
+ ..add(17099)
+ ..add(17100)
+ ..add(17101)
+ ..add(17102)
+ ..add(17103)
+ ..add(17104)
+ ..add(17105)
+ ..add(17106)
+ ..add(17107)
+ ..add(17108)
+ ..add(17109)
+ ..add(17110)
+ ..add(17111)
+ ..add(17112)
+ ..add(17113)
+ ..add(17114)
+ ..add(17115)
+ ..add(17116)
+ ..add(17117)
+ ..add(17118)
+ ..add(17119)
+ ..add(17120)
+ ..add(17121)
+ ..add(17122)
+ ..add(17123)
+ ..add(17124)
+ ..add(17125)
+ ..add(17126)
+ ..add(17127)
+ ..add(17128)
+ ..add(17129)
+ ..add(17130)
+ ..add(17131)
+ ..add(17132)
+ ..add(17133)
+ ..add(17134)
+ ..add(17135)
+ ..add(17136)
+ ..add(17137)
+ ..add(17138)
+ ..add(17139)
+ ..add(17140)
+ ..add(17141)
+ ..add(17142)
+ ..add(17143)
+ ..add(17144)
+ ..add(17145)
+ ..add(17146)
+ ..add(17147)
+ ..add(17148)
+ ..add(17149)
+ ..add(17150)
+ ..add(17151)
+ ..add(17152)
+ ..add(17153)
+ ..add(17154)
+ ..add(17155)
+ ..add(17156)
+ ..add(17157)
+ ..add(17158)
+ ..add(17159)
+ ..add(17160)
+ ..add(17161)
+ ..add(17162)
+ ..add(17163)
+ ..add(17164)
+ ..add(17165)
+ ..add(17166)
+ ..add(17167)
+ ..add(17168)
+ ..add(17169)
+ ..add(17170)
+ ..add(17171)
+ ..add(17172)
+ ..add(17173)
+ ..add(17174)
+ ..add(17175)
+ ..add(17176)
+ ..add(17177)
+ ..add(17178)
+ ..add(17179)
+ ..add(17180)
+ ..add(17181)
+ ..add(17182)
+ ..add(17183)
+ ..add(17184)
+ ..add(17185)
+ ..add(17186)
+ ..add(17187)
+ ..add(17188)
+ ..add(17189)
+ ..add(17190)
+ ..add(17191)
+ ..add(17192)
+ ..add(17193)
+ ..add(17194)
+ ..add(17195)
+ ..add(17196)
+ ..add(17197)
+ ..add(17198)
+ ..add(17199)
+ ..add(17200)
+ ..add(17201)
+ ..add(17202)
+ ..add(17203)
+ ..add(17204)
+ ..add(17205)
+ ..add(17206)
+ ..add(17207)
+ ..add(17208)
+ ..add(17209)
+ ..add(17210)
+ ..add(17211)
+ ..add(17212)
+ ..add(17213)
+ ..add(17214)
+ ..add(17215)
+ ..add(17216)
+ ..add(17217)
+ ..add(17218)
+ ..add(17219)
+ ..add(17220)
+ ..add(17221)
+ ..add(17222)
+ ..add(17223)
+ ..add(17224)
+ ..add(17225)
+ ..add(17226)
+ ..add(17227)
+ ..add(17228)
+ ..add(17229)
+ ..add(17230)
+ ..add(17231)
+ ..add(17232)
+ ..add(17233)
+ ..add(17234)
+ ..add(17235)
+ ..add(17236)
+ ..add(17237)
+ ..add(17238)
+ ..add(17239)
+ ..add(17240)
+ ..add(17241)
+ ..add(17242)
+ ..add(17243)
+ ..add(17244)
+ ..add(17245)
+ ..add(17246)
+ ..add(17247)
+ ..add(17248)
+ ..add(17249)
+ ..add(17250)
+ ..add(17251)
+ ..add(17252)
+ ..add(17253)
+ ..add(17254)
+ ..add(17255)
+ ..add(17256)
+ ..add(17257)
+ ..add(17258)
+ ..add(17259)
+ ..add(17260)
+ ..add(17261)
+ ..add(17262)
+ ..add(17263)
+ ..add(17264)
+ ..add(17265)
+ ..add(17266)
+ ..add(17267)
+ ..add(17268)
+ ..add(17269)
+ ..add(17270)
+ ..add(17271)
+ ..add(17272)
+ ..add(17273)
+ ..add(17274)
+ ..add(17275)
+ ..add(17276)
+ ..add(17277)
+ ..add(17278)
+ ..add(17279)
+ ..add(17280)
+ ..add(17281)
+ ..add(17282)
+ ..add(17283)
+ ..add(17284)
+ ..add(17285)
+ ..add(17286)
+ ..add(17287)
+ ..add(17288)
+ ..add(17289)
+ ..add(17290)
+ ..add(17291)
+ ..add(17292)
+ ..add(17293)
+ ..add(17294)
+ ..add(17295)
+ ..add(17296)
+ ..add(17297)
+ ..add(17298)
+ ..add(17299)
+ ..add(17300)
+ ..add(17301)
+ ..add(17302)
+ ..add(17303)
+ ..add(17304)
+ ..add(17305)
+ ..add(17306)
+ ..add(17307)
+ ..add(17308)
+ ..add(17309)
+ ..add(17310)
+ ..add(17311)
+ ..add(17312)
+ ..add(17313)
+ ..add(17314)
+ ..add(17315)
+ ..add(17316)
+ ..add(17317)
+ ..add(17318)
+ ..add(17319)
+ ..add(17320)
+ ..add(17321)
+ ..add(17322)
+ ..add(17323)
+ ..add(17324)
+ ..add(17325)
+ ..add(17326)
+ ..add(17327)
+ ..add(17328)
+ ..add(17329)
+ ..add(17330)
+ ..add(17331)
+ ..add(17332)
+ ..add(17333)
+ ..add(17334)
+ ..add(17335)
+ ..add(17336)
+ ..add(17337)
+ ..add(17338)
+ ..add(17339)
+ ..add(17340)
+ ..add(17341)
+ ..add(17342)
+ ..add(17343)
+ ..add(17344)
+ ..add(17345)
+ ..add(17346)
+ ..add(17347)
+ ..add(17348)
+ ..add(17349)
+ ..add(17350)
+ ..add(17351)
+ ..add(17352)
+ ..add(17353)
+ ..add(17354)
+ ..add(17355)
+ ..add(17356)
+ ..add(17357)
+ ..add(17358)
+ ..add(17359)
+ ..add(17360)
+ ..add(17361)
+ ..add(17362)
+ ..add(17363)
+ ..add(17364)
+ ..add(17365)
+ ..add(17366)
+ ..add(17367)
+ ..add(17368)
+ ..add(17369)
+ ..add(17370)
+ ..add(17371)
+ ..add(17372)
+ ..add(17373)
+ ..add(17374)
+ ..add(17375)
+ ..add(17376)
+ ..add(17377)
+ ..add(17378)
+ ..add(17379)
+ ..add(17380)
+ ..add(17381)
+ ..add(17382)
+ ..add(17383)
+ ..add(17384)
+ ..add(17385)
+ ..add(17386)
+ ..add(17387)
+ ..add(17388)
+ ..add(17389)
+ ..add(17390)
+ ..add(17391)
+ ..add(17392)
+ ..add(17393)
+ ..add(17394)
+ ..add(17395)
+ ..add(17396)
+ ..add(17397)
+ ..add(17398)
+ ..add(17399)
+ ..add(17400)
+ ..add(17401)
+ ..add(17402)
+ ..add(17403)
+ ..add(17404)
+ ..add(17405)
+ ..add(17406)
+ ..add(17407)
+ ..add(17408)
+ ..add(17409)
+ ..add(17410)
+ ..add(17411)
+ ..add(17412)
+ ..add(17413)
+ ..add(17414)
+ ..add(17415)
+ ..add(17416)
+ ..add(17417)
+ ..add(17418)
+ ..add(17419)
+ ..add(17420)
+ ..add(17421)
+ ..add(17422)
+ ..add(17423)
+ ..add(17424)
+ ..add(17425)
+ ..add(17426)
+ ..add(17427)
+ ..add(17428)
+ ..add(17429)
+ ..add(17430)
+ ..add(17431)
+ ..add(17432)
+ ..add(17433)
+ ..add(17434)
+ ..add(17435)
+ ..add(17436)
+ ..add(17437)
+ ..add(17438)
+ ..add(17439)
+ ..add(17440)
+ ..add(17441)
+ ..add(17442)
+ ..add(17443)
+ ..add(17444)
+ ..add(17445)
+ ..add(17446)
+ ..add(17447)
+ ..add(17448)
+ ..add(17449)
+ ..add(17450)
+ ..add(17451)
+ ..add(17452)
+ ..add(17453)
+ ..add(17454)
+ ..add(17455)
+ ..add(17456)
+ ..add(17457)
+ ..add(17458)
+ ..add(17459)
+ ..add(17460)
+ ..add(17461)
+ ..add(17462)
+ ..add(17463)
+ ..add(17464)
+ ..add(17465)
+ ..add(17466)
+ ..add(17467)
+ ..add(17468)
+ ..add(17469)
+ ..add(17470)
+ ..add(17471)
+ ..add(17472)
+ ..add(17473)
+ ..add(17474)
+ ..add(17475)
+ ..add(17476)
+ ..add(17477)
+ ..add(17478)
+ ..add(17479)
+ ..add(17480)
+ ..add(17481)
+ ..add(17482)
+ ..add(17483)
+ ..add(17484)
+ ..add(17485)
+ ..add(17486)
+ ..add(17487)
+ ..add(17488)
+ ..add(17489)
+ ..add(17490)
+ ..add(17491)
+ ..add(17492)
+ ..add(17493)
+ ..add(17494)
+ ..add(17495)
+ ..add(17496)
+ ..add(17497)
+ ..add(17498)
+ ..add(17499)
+ ..add(17500)
+ ..add(17501)
+ ..add(17502)
+ ..add(17503)
+ ..add(17504)
+ ..add(17505)
+ ..add(17506)
+ ..add(17507)
+ ..add(17508)
+ ..add(17509)
+ ..add(17510)
+ ..add(17511)
+ ..add(17512)
+ ..add(17513)
+ ..add(17514)
+ ..add(17515)
+ ..add(17516)
+ ..add(17517)
+ ..add(17518)
+ ..add(17519)
+ ..add(17520)
+ ..add(17521)
+ ..add(17522)
+ ..add(17523)
+ ..add(17524)
+ ..add(17525)
+ ..add(17526)
+ ..add(17527)
+ ..add(17528)
+ ..add(17529)
+ ..add(17530)
+ ..add(17531)
+ ..add(17532)
+ ..add(17533)
+ ..add(17534)
+ ..add(17535)
+ ..add(17536)
+ ..add(17537)
+ ..add(17538)
+ ..add(17539)
+ ..add(17540)
+ ..add(17541)
+ ..add(17542)
+ ..add(17543)
+ ..add(17544)
+ ..add(17545)
+ ..add(17546)
+ ..add(17547)
+ ..add(17548)
+ ..add(17549)
+ ..add(17550)
+ ..add(17551)
+ ..add(17552)
+ ..add(17553)
+ ..add(17554)
+ ..add(17555)
+ ..add(17556)
+ ..add(17557)
+ ..add(17558)
+ ..add(17559)
+ ..add(17560)
+ ..add(17561)
+ ..add(17562)
+ ..add(17563)
+ ..add(17564)
+ ..add(17565)
+ ..add(17566)
+ ..add(17567)
+ ..add(17568)
+ ..add(17569)
+ ..add(17570)
+ ..add(17571)
+ ..add(17572)
+ ..add(17573)
+ ..add(17574)
+ ..add(17575)
+ ..add(17576)
+ ..add(17577)
+ ..add(17578)
+ ..add(17579)
+ ..add(17580)
+ ..add(17581)
+ ..add(17582)
+ ..add(17583)
+ ..add(17584)
+ ..add(17585)
+ ..add(17586)
+ ..add(17587)
+ ..add(17588)
+ ..add(17589)
+ ..add(17590)
+ ..add(17591)
+ ..add(17592)
+ ..add(17593)
+ ..add(17594)
+ ..add(17595)
+ ..add(17596)
+ ..add(17597)
+ ..add(17598)
+ ..add(17599)
+ ..add(17600)
+ ..add(17601)
+ ..add(17602)
+ ..add(17603)
+ ..add(17604)
+ ..add(17605)
+ ..add(17606)
+ ..add(17607)
+ ..add(17608)
+ ..add(17609)
+ ..add(17610)
+ ..add(17611)
+ ..add(17612)
+ ..add(17613)
+ ..add(17614)
+ ..add(17615)
+ ..add(17616)
+ ..add(17617)
+ ..add(17618)
+ ..add(17619)
+ ..add(17620)
+ ..add(17621)
+ ..add(17622)
+ ..add(17623)
+ ..add(17624)
+ ..add(17625)
+ ..add(17626)
+ ..add(17627)
+ ..add(17628)
+ ..add(17629)
+ ..add(17630)
+ ..add(17631)
+ ..add(17632)
+ ..add(17633)
+ ..add(17634)
+ ..add(17635)
+ ..add(17636)
+ ..add(17637)
+ ..add(17638)
+ ..add(17639)
+ ..add(17640)
+ ..add(17641)
+ ..add(17642)
+ ..add(17643)
+ ..add(17644)
+ ..add(17645)
+ ..add(17646)
+ ..add(17647)
+ ..add(17648)
+ ..add(17649)
+ ..add(17650)
+ ..add(17651)
+ ..add(17652)
+ ..add(17653)
+ ..add(17654)
+ ..add(17655)
+ ..add(17656)
+ ..add(17657)
+ ..add(17658)
+ ..add(17659)
+ ..add(17660)
+ ..add(17661)
+ ..add(17662)
+ ..add(17663)
+ ..add(17664)
+ ..add(17665)
+ ..add(17666)
+ ..add(17667)
+ ..add(17668)
+ ..add(17669)
+ ..add(17670)
+ ..add(17671)
+ ..add(17672)
+ ..add(17673)
+ ..add(17674)
+ ..add(17675)
+ ..add(17676)
+ ..add(17677)
+ ..add(17678)
+ ..add(17679)
+ ..add(17680)
+ ..add(17681)
+ ..add(17682)
+ ..add(17683)
+ ..add(17684)
+ ..add(17685)
+ ..add(17686)
+ ..add(17687)
+ ..add(17688)
+ ..add(17689)
+ ..add(17690)
+ ..add(17691)
+ ..add(17692)
+ ..add(17693)
+ ..add(17694)
+ ..add(17695)
+ ..add(17696)
+ ..add(17697)
+ ..add(17698)
+ ..add(17699)
+ ..add(17700)
+ ..add(17701)
+ ..add(17702)
+ ..add(17703)
+ ..add(17704)
+ ..add(17705)
+ ..add(17706)
+ ..add(17707)
+ ..add(17708)
+ ..add(17709)
+ ..add(17710)
+ ..add(17711)
+ ..add(17712)
+ ..add(17713)
+ ..add(17714)
+ ..add(17715)
+ ..add(17716)
+ ..add(17717)
+ ..add(17718)
+ ..add(17719)
+ ..add(17720)
+ ..add(17721)
+ ..add(17722)
+ ..add(17723)
+ ..add(17724)
+ ..add(17725)
+ ..add(17726)
+ ..add(17727)
+ ..add(17728)
+ ..add(17729)
+ ..add(17730)
+ ..add(17731)
+ ..add(17732)
+ ..add(17733)
+ ..add(17734)
+ ..add(17735)
+ ..add(17736)
+ ..add(17737)
+ ..add(17738)
+ ..add(17739)
+ ..add(17740)
+ ..add(17741)
+ ..add(17742)
+ ..add(17743)
+ ..add(17744)
+ ..add(17745)
+ ..add(17746)
+ ..add(17747)
+ ..add(17748)
+ ..add(17749)
+ ..add(17750)
+ ..add(17751)
+ ..add(17752)
+ ..add(17753)
+ ..add(17754)
+ ..add(17755)
+ ..add(17756)
+ ..add(17757)
+ ..add(17758)
+ ..add(17759)
+ ..add(17760)
+ ..add(17761)
+ ..add(17762)
+ ..add(17763)
+ ..add(17764)
+ ..add(17765)
+ ..add(17766)
+ ..add(17767)
+ ..add(17768)
+ ..add(17769)
+ ..add(17770)
+ ..add(17771)
+ ..add(17772)
+ ..add(17773)
+ ..add(17774)
+ ..add(17775)
+ ..add(17776)
+ ..add(17777)
+ ..add(17778)
+ ..add(17779)
+ ..add(17780)
+ ..add(17781)
+ ..add(17782)
+ ..add(17783)
+ ..add(17784)
+ ..add(17785)
+ ..add(17786)
+ ..add(17787)
+ ..add(17788)
+ ..add(17789)
+ ..add(17790)
+ ..add(17791)
+ ..add(17792)
+ ..add(17793)
+ ..add(17794)
+ ..add(17795)
+ ..add(17796)
+ ..add(17797)
+ ..add(17798)
+ ..add(17799)
+ ..add(17800)
+ ..add(17801)
+ ..add(17802)
+ ..add(17803)
+ ..add(17804)
+ ..add(17805)
+ ..add(17806)
+ ..add(17807)
+ ..add(17808)
+ ..add(17809)
+ ..add(17810)
+ ..add(17811)
+ ..add(17812)
+ ..add(17813)
+ ..add(17814)
+ ..add(17815)
+ ..add(17816)
+ ..add(17817)
+ ..add(17818)
+ ..add(17819)
+ ..add(17820)
+ ..add(17821)
+ ..add(17822)
+ ..add(17823)
+ ..add(17824)
+ ..add(17825)
+ ..add(17826)
+ ..add(17827)
+ ..add(17828)
+ ..add(17829)
+ ..add(17830)
+ ..add(17831)
+ ..add(17832)
+ ..add(17833)
+ ..add(17834)
+ ..add(17835)
+ ..add(17836)
+ ..add(17837)
+ ..add(17838)
+ ..add(17839)
+ ..add(17840)
+ ..add(17841)
+ ..add(17842)
+ ..add(17843)
+ ..add(17844)
+ ..add(17845)
+ ..add(17846)
+ ..add(17847)
+ ..add(17848)
+ ..add(17849)
+ ..add(17850)
+ ..add(17851)
+ ..add(17852)
+ ..add(17853)
+ ..add(17854)
+ ..add(17855)
+ ..add(17856)
+ ..add(17857)
+ ..add(17858)
+ ..add(17859)
+ ..add(17860)
+ ..add(17861)
+ ..add(17862)
+ ..add(17863)
+ ..add(17864)
+ ..add(17865)
+ ..add(17866)
+ ..add(17867)
+ ..add(17868)
+ ..add(17869)
+ ..add(17870)
+ ..add(17871)
+ ..add(17872)
+ ..add(17873)
+ ..add(17874)
+ ..add(17875)
+ ..add(17876)
+ ..add(17877)
+ ..add(17878)
+ ..add(17879)
+ ..add(17880)
+ ..add(17881)
+ ..add(17882)
+ ..add(17883)
+ ..add(17884)
+ ..add(17885)
+ ..add(17886)
+ ..add(17887)
+ ..add(17888)
+ ..add(17889)
+ ..add(17890)
+ ..add(17891)
+ ..add(17892)
+ ..add(17893)
+ ..add(17894)
+ ..add(17895)
+ ..add(17896)
+ ..add(17897)
+ ..add(17898)
+ ..add(17899)
+ ..add(17900)
+ ..add(17901)
+ ..add(17902)
+ ..add(17903)
+ ..add(17904)
+ ..add(17905)
+ ..add(17906)
+ ..add(17907)
+ ..add(17908)
+ ..add(17909)
+ ..add(17910)
+ ..add(17911)
+ ..add(17912)
+ ..add(17913)
+ ..add(17914)
+ ..add(17915)
+ ..add(17916)
+ ..add(17917)
+ ..add(17918)
+ ..add(17919)
+ ..add(17920)
+ ..add(17921)
+ ..add(17922)
+ ..add(17923)
+ ..add(17924)
+ ..add(17925)
+ ..add(17926)
+ ..add(17927)
+ ..add(17928)
+ ..add(17929)
+ ..add(17930)
+ ..add(17931)
+ ..add(17932)
+ ..add(17933)
+ ..add(17934)
+ ..add(17935)
+ ..add(17936)
+ ..add(17937)
+ ..add(17938)
+ ..add(17939)
+ ..add(17940)
+ ..add(17941)
+ ..add(17942)
+ ..add(17943)
+ ..add(17944)
+ ..add(17945)
+ ..add(17946)
+ ..add(17947)
+ ..add(17948)
+ ..add(17949)
+ ..add(17950)
+ ..add(17951)
+ ..add(17952)
+ ..add(17953)
+ ..add(17954)
+ ..add(17955)
+ ..add(17956)
+ ..add(17957)
+ ..add(17958)
+ ..add(17959)
+ ..add(17960)
+ ..add(17961)
+ ..add(17962)
+ ..add(17963)
+ ..add(17964)
+ ..add(17965)
+ ..add(17966)
+ ..add(17967)
+ ..add(17968)
+ ..add(17969)
+ ..add(17970)
+ ..add(17971)
+ ..add(17972)
+ ..add(17973)
+ ..add(17974)
+ ..add(17975)
+ ..add(17976)
+ ..add(17977)
+ ..add(17978)
+ ..add(17979)
+ ..add(17980)
+ ..add(17981)
+ ..add(17982)
+ ..add(17983)
+ ..add(17984)
+ ..add(17985)
+ ..add(17986)
+ ..add(17987)
+ ..add(17988)
+ ..add(17989)
+ ..add(17990)
+ ..add(17991)
+ ..add(17992)
+ ..add(17993)
+ ..add(17994)
+ ..add(17995)
+ ..add(17996)
+ ..add(17997)
+ ..add(17998)
+ ..add(17999)
+ ..add(18000)
+ ..add(18001)
+ ..add(18002)
+ ..add(18003)
+ ..add(18004)
+ ..add(18005)
+ ..add(18006)
+ ..add(18007)
+ ..add(18008)
+ ..add(18009)
+ ..add(18010)
+ ..add(18011)
+ ..add(18012)
+ ..add(18013)
+ ..add(18014)
+ ..add(18015)
+ ..add(18016)
+ ..add(18017)
+ ..add(18018)
+ ..add(18019)
+ ..add(18020)
+ ..add(18021)
+ ..add(18022)
+ ..add(18023)
+ ..add(18024)
+ ..add(18025)
+ ..add(18026)
+ ..add(18027)
+ ..add(18028)
+ ..add(18029)
+ ..add(18030)
+ ..add(18031)
+ ..add(18032)
+ ..add(18033)
+ ..add(18034)
+ ..add(18035)
+ ..add(18036)
+ ..add(18037)
+ ..add(18038)
+ ..add(18039)
+ ..add(18040)
+ ..add(18041)
+ ..add(18042)
+ ..add(18043)
+ ..add(18044)
+ ..add(18045)
+ ..add(18046)
+ ..add(18047)
+ ..add(18048)
+ ..add(18049)
+ ..add(18050)
+ ..add(18051)
+ ..add(18052)
+ ..add(18053)
+ ..add(18054)
+ ..add(18055)
+ ..add(18056)
+ ..add(18057)
+ ..add(18058)
+ ..add(18059)
+ ..add(18060)
+ ..add(18061)
+ ..add(18062)
+ ..add(18063)
+ ..add(18064)
+ ..add(18065)
+ ..add(18066)
+ ..add(18067)
+ ..add(18068)
+ ..add(18069)
+ ..add(18070)
+ ..add(18071)
+ ..add(18072)
+ ..add(18073)
+ ..add(18074)
+ ..add(18075)
+ ..add(18076)
+ ..add(18077)
+ ..add(18078)
+ ..add(18079)
+ ..add(18080)
+ ..add(18081)
+ ..add(18082)
+ ..add(18083)
+ ..add(18084)
+ ..add(18085)
+ ..add(18086)
+ ..add(18087)
+ ..add(18088)
+ ..add(18089)
+ ..add(18090)
+ ..add(18091)
+ ..add(18092)
+ ..add(18093)
+ ..add(18094)
+ ..add(18095)
+ ..add(18096)
+ ..add(18097)
+ ..add(18098)
+ ..add(18099)
+ ..add(18100)
+ ..add(18101)
+ ..add(18102)
+ ..add(18103)
+ ..add(18104)
+ ..add(18105)
+ ..add(18106)
+ ..add(18107)
+ ..add(18108)
+ ..add(18109)
+ ..add(18110)
+ ..add(18111)
+ ..add(18112)
+ ..add(18113)
+ ..add(18114)
+ ..add(18115)
+ ..add(18116)
+ ..add(18117)
+ ..add(18118)
+ ..add(18119)
+ ..add(18120)
+ ..add(18121)
+ ..add(18122)
+ ..add(18123)
+ ..add(18124)
+ ..add(18125)
+ ..add(18126)
+ ..add(18127)
+ ..add(18128)
+ ..add(18129)
+ ..add(18130)
+ ..add(18131)
+ ..add(18132)
+ ..add(18133)
+ ..add(18134)
+ ..add(18135)
+ ..add(18136)
+ ..add(18137)
+ ..add(18138)
+ ..add(18139)
+ ..add(18140)
+ ..add(18141)
+ ..add(18142)
+ ..add(18143)
+ ..add(18144)
+ ..add(18145)
+ ..add(18146)
+ ..add(18147)
+ ..add(18148)
+ ..add(18149)
+ ..add(18150)
+ ..add(18151)
+ ..add(18152)
+ ..add(18153)
+ ..add(18154)
+ ..add(18155)
+ ..add(18156)
+ ..add(18157)
+ ..add(18158)
+ ..add(18159)
+ ..add(18160)
+ ..add(18161)
+ ..add(18162)
+ ..add(18163)
+ ..add(18164)
+ ..add(18165)
+ ..add(18166)
+ ..add(18167)
+ ..add(18168)
+ ..add(18169)
+ ..add(18170)
+ ..add(18171)
+ ..add(18172)
+ ..add(18173)
+ ..add(18174)
+ ..add(18175)
+ ..add(18176)
+ ..add(18177)
+ ..add(18178)
+ ..add(18179)
+ ..add(18180)
+ ..add(18181)
+ ..add(18182)
+ ..add(18183)
+ ..add(18184)
+ ..add(18185)
+ ..add(18186)
+ ..add(18187)
+ ..add(18188)
+ ..add(18189)
+ ..add(18190)
+ ..add(18191)
+ ..add(18192)
+ ..add(18193)
+ ..add(18194)
+ ..add(18195)
+ ..add(18196)
+ ..add(18197)
+ ..add(18198)
+ ..add(18199)
+ ..add(18200)
+ ..add(18201)
+ ..add(18202)
+ ..add(18203)
+ ..add(18204)
+ ..add(18205)
+ ..add(18206)
+ ..add(18207)
+ ..add(18208)
+ ..add(18209)
+ ..add(18210)
+ ..add(18211)
+ ..add(18212)
+ ..add(18213)
+ ..add(18214)
+ ..add(18215)
+ ..add(18216)
+ ..add(18217)
+ ..add(18218)
+ ..add(18219)
+ ..add(18220)
+ ..add(18221)
+ ..add(18222)
+ ..add(18223)
+ ..add(18224)
+ ..add(18225)
+ ..add(18226)
+ ..add(18227)
+ ..add(18228)
+ ..add(18229)
+ ..add(18230)
+ ..add(18231)
+ ..add(18232)
+ ..add(18233)
+ ..add(18234)
+ ..add(18235)
+ ..add(18236)
+ ..add(18237)
+ ..add(18238)
+ ..add(18239)
+ ..add(18240)
+ ..add(18241)
+ ..add(18242)
+ ..add(18243)
+ ..add(18244)
+ ..add(18245)
+ ..add(18246)
+ ..add(18247)
+ ..add(18248)
+ ..add(18249)
+ ..add(18250)
+ ..add(18251)
+ ..add(18252)
+ ..add(18253)
+ ..add(18254)
+ ..add(18255)
+ ..add(18256)
+ ..add(18257)
+ ..add(18258)
+ ..add(18259)
+ ..add(18260)
+ ..add(18261)
+ ..add(18262)
+ ..add(18263)
+ ..add(18264)
+ ..add(18265)
+ ..add(18266)
+ ..add(18267)
+ ..add(18268)
+ ..add(18269)
+ ..add(18270)
+ ..add(18271)
+ ..add(18272)
+ ..add(18273)
+ ..add(18274)
+ ..add(18275)
+ ..add(18276)
+ ..add(18277)
+ ..add(18278)
+ ..add(18279)
+ ..add(18280)
+ ..add(18281)
+ ..add(18282)
+ ..add(18283)
+ ..add(18284)
+ ..add(18285)
+ ..add(18286)
+ ..add(18287)
+ ..add(18288)
+ ..add(18289)
+ ..add(18290)
+ ..add(18291)
+ ..add(18292)
+ ..add(18293)
+ ..add(18294)
+ ..add(18295)
+ ..add(18296)
+ ..add(18297)
+ ..add(18298)
+ ..add(18299)
+ ..add(18300)
+ ..add(18301)
+ ..add(18302)
+ ..add(18303)
+ ..add(18304)
+ ..add(18305)
+ ..add(18306)
+ ..add(18307)
+ ..add(18308)
+ ..add(18309)
+ ..add(18310)
+ ..add(18311)
+ ..add(18312)
+ ..add(18313)
+ ..add(18314)
+ ..add(18315)
+ ..add(18316)
+ ..add(18317)
+ ..add(18318)
+ ..add(18319)
+ ..add(18320)
+ ..add(18321)
+ ..add(18322)
+ ..add(18323)
+ ..add(18324)
+ ..add(18325)
+ ..add(18326)
+ ..add(18327)
+ ..add(18328)
+ ..add(18329)
+ ..add(18330)
+ ..add(18331)
+ ..add(18332)
+ ..add(18333)
+ ..add(18334)
+ ..add(18335)
+ ..add(18336)
+ ..add(18337)
+ ..add(18338)
+ ..add(18339)
+ ..add(18340)
+ ..add(18341)
+ ..add(18342)
+ ..add(18343)
+ ..add(18344)
+ ..add(18345)
+ ..add(18346)
+ ..add(18347)
+ ..add(18348)
+ ..add(18349)
+ ..add(18350)
+ ..add(18351)
+ ..add(18352)
+ ..add(18353)
+ ..add(18354)
+ ..add(18355)
+ ..add(18356)
+ ..add(18357)
+ ..add(18358)
+ ..add(18359)
+ ..add(18360)
+ ..add(18361)
+ ..add(18362)
+ ..add(18363)
+ ..add(18364)
+ ..add(18365)
+ ..add(18366)
+ ..add(18367)
+ ..add(18368)
+ ..add(18369)
+ ..add(18370)
+ ..add(18371)
+ ..add(18372)
+ ..add(18373)
+ ..add(18374)
+ ..add(18375)
+ ..add(18376)
+ ..add(18377)
+ ..add(18378)
+ ..add(18379)
+ ..add(18380)
+ ..add(18381)
+ ..add(18382)
+ ..add(18383)
+ ..add(18384)
+ ..add(18385)
+ ..add(18386)
+ ..add(18387)
+ ..add(18388)
+ ..add(18389)
+ ..add(18390)
+ ..add(18391)
+ ..add(18392)
+ ..add(18393)
+ ..add(18394)
+ ..add(18395)
+ ..add(18396)
+ ..add(18397)
+ ..add(18398)
+ ..add(18399)
+ ..add(18400)
+ ..add(18401)
+ ..add(18402)
+ ..add(18403)
+ ..add(18404)
+ ..add(18405)
+ ..add(18406)
+ ..add(18407)
+ ..add(18408)
+ ..add(18409)
+ ..add(18410)
+ ..add(18411)
+ ..add(18412)
+ ..add(18413)
+ ..add(18414)
+ ..add(18415)
+ ..add(18416)
+ ..add(18417)
+ ..add(18418)
+ ..add(18419)
+ ..add(18420)
+ ..add(18421)
+ ..add(18422)
+ ..add(18423)
+ ..add(18424)
+ ..add(18425)
+ ..add(18426)
+ ..add(18427)
+ ..add(18428)
+ ..add(18429)
+ ..add(18430)
+ ..add(18431)
+ ..add(18432)
+ ..add(18433)
+ ..add(18434)
+ ..add(18435)
+ ..add(18436)
+ ..add(18437)
+ ..add(18438)
+ ..add(18439)
+ ..add(18440)
+ ..add(18441)
+ ..add(18442)
+ ..add(18443)
+ ..add(18444)
+ ..add(18445)
+ ..add(18446)
+ ..add(18447)
+ ..add(18448)
+ ..add(18449)
+ ..add(18450)
+ ..add(18451)
+ ..add(18452)
+ ..add(18453)
+ ..add(18454)
+ ..add(18455)
+ ..add(18456)
+ ..add(18457)
+ ..add(18458)
+ ..add(18459)
+ ..add(18460)
+ ..add(18461)
+ ..add(18462)
+ ..add(18463)
+ ..add(18464)
+ ..add(18465)
+ ..add(18466)
+ ..add(18467)
+ ..add(18468)
+ ..add(18469)
+ ..add(18470)
+ ..add(18471)
+ ..add(18472)
+ ..add(18473)
+ ..add(18474)
+ ..add(18475)
+ ..add(18476)
+ ..add(18477)
+ ..add(18478)
+ ..add(18479)
+ ..add(18480)
+ ..add(18481)
+ ..add(18482)
+ ..add(18483)
+ ..add(18484)
+ ..add(18485)
+ ..add(18486)
+ ..add(18487)
+ ..add(18488)
+ ..add(18489)
+ ..add(18490)
+ ..add(18491)
+ ..add(18492)
+ ..add(18493)
+ ..add(18494)
+ ..add(18495)
+ ..add(18496)
+ ..add(18497)
+ ..add(18498)
+ ..add(18499)
+ ..add(18500)
+ ..add(18501)
+ ..add(18502)
+ ..add(18503)
+ ..add(18504)
+ ..add(18505)
+ ..add(18506)
+ ..add(18507)
+ ..add(18508)
+ ..add(18509)
+ ..add(18510)
+ ..add(18511)
+ ..add(18512)
+ ..add(18513)
+ ..add(18514)
+ ..add(18515)
+ ..add(18516)
+ ..add(18517)
+ ..add(18518)
+ ..add(18519)
+ ..add(18520)
+ ..add(18521)
+ ..add(18522)
+ ..add(18523)
+ ..add(18524)
+ ..add(18525)
+ ..add(18526)
+ ..add(18527)
+ ..add(18528)
+ ..add(18529)
+ ..add(18530)
+ ..add(18531)
+ ..add(18532)
+ ..add(18533)
+ ..add(18534)
+ ..add(18535)
+ ..add(18536)
+ ..add(18537)
+ ..add(18538)
+ ..add(18539)
+ ..add(18540)
+ ..add(18541)
+ ..add(18542)
+ ..add(18543)
+ ..add(18544)
+ ..add(18545)
+ ..add(18546)
+ ..add(18547)
+ ..add(18548)
+ ..add(18549)
+ ..add(18550)
+ ..add(18551)
+ ..add(18552)
+ ..add(18553)
+ ..add(18554)
+ ..add(18555)
+ ..add(18556)
+ ..add(18557)
+ ..add(18558)
+ ..add(18559)
+ ..add(18560)
+ ..add(18561)
+ ..add(18562)
+ ..add(18563)
+ ..add(18564)
+ ..add(18565)
+ ..add(18566)
+ ..add(18567)
+ ..add(18568)
+ ..add(18569)
+ ..add(18570)
+ ..add(18571)
+ ..add(18572)
+ ..add(18573)
+ ..add(18574)
+ ..add(18575)
+ ..add(18576)
+ ..add(18577)
+ ..add(18578)
+ ..add(18579)
+ ..add(18580)
+ ..add(18581)
+ ..add(18582)
+ ..add(18583)
+ ..add(18584)
+ ..add(18585)
+ ..add(18586)
+ ..add(18587)
+ ..add(18588)
+ ..add(18589)
+ ..add(18590)
+ ..add(18591)
+ ..add(18592)
+ ..add(18593)
+ ..add(18594)
+ ..add(18595)
+ ..add(18596)
+ ..add(18597)
+ ..add(18598)
+ ..add(18599)
+ ..add(18600)
+ ..add(18601)
+ ..add(18602)
+ ..add(18603)
+ ..add(18604)
+ ..add(18605)
+ ..add(18606)
+ ..add(18607)
+ ..add(18608)
+ ..add(18609)
+ ..add(18610)
+ ..add(18611)
+ ..add(18612)
+ ..add(18613)
+ ..add(18614)
+ ..add(18615)
+ ..add(18616)
+ ..add(18617)
+ ..add(18618)
+ ..add(18619)
+ ..add(18620)
+ ..add(18621)
+ ..add(18622)
+ ..add(18623)
+ ..add(18624)
+ ..add(18625)
+ ..add(18626)
+ ..add(18627)
+ ..add(18628)
+ ..add(18629)
+ ..add(18630)
+ ..add(18631)
+ ..add(18632)
+ ..add(18633)
+ ..add(18634)
+ ..add(18635)
+ ..add(18636)
+ ..add(18637)
+ ..add(18638)
+ ..add(18639)
+ ..add(18640)
+ ..add(18641)
+ ..add(18642)
+ ..add(18643)
+ ..add(18644)
+ ..add(18645)
+ ..add(18646)
+ ..add(18647)
+ ..add(18648)
+ ..add(18649)
+ ..add(18650)
+ ..add(18651)
+ ..add(18652)
+ ..add(18653)
+ ..add(18654)
+ ..add(18655)
+ ..add(18656)
+ ..add(18657)
+ ..add(18658)
+ ..add(18659)
+ ..add(18660)
+ ..add(18661)
+ ..add(18662)
+ ..add(18663)
+ ..add(18664)
+ ..add(18665)
+ ..add(18666)
+ ..add(18667)
+ ..add(18668)
+ ..add(18669)
+ ..add(18670)
+ ..add(18671)
+ ..add(18672)
+ ..add(18673)
+ ..add(18674)
+ ..add(18675)
+ ..add(18676)
+ ..add(18677)
+ ..add(18678)
+ ..add(18679)
+ ..add(18680)
+ ..add(18681)
+ ..add(18682)
+ ..add(18683)
+ ..add(18684)
+ ..add(18685)
+ ..add(18686)
+ ..add(18687)
+ ..add(18688)
+ ..add(18689)
+ ..add(18690)
+ ..add(18691)
+ ..add(18692)
+ ..add(18693)
+ ..add(18694)
+ ..add(18695)
+ ..add(18696)
+ ..add(18697)
+ ..add(18698)
+ ..add(18699)
+ ..add(18700)
+ ..add(18701)
+ ..add(18702)
+ ..add(18703)
+ ..add(18704)
+ ..add(18705)
+ ..add(18706)
+ ..add(18707)
+ ..add(18708)
+ ..add(18709)
+ ..add(18710)
+ ..add(18711)
+ ..add(18712)
+ ..add(18713)
+ ..add(18714)
+ ..add(18715)
+ ..add(18716)
+ ..add(18717)
+ ..add(18718)
+ ..add(18719)
+ ..add(18720)
+ ..add(18721)
+ ..add(18722)
+ ..add(18723)
+ ..add(18724)
+ ..add(18725)
+ ..add(18726)
+ ..add(18727)
+ ..add(18728)
+ ..add(18729)
+ ..add(18730)
+ ..add(18731)
+ ..add(18732)
+ ..add(18733)
+ ..add(18734)
+ ..add(18735)
+ ..add(18736)
+ ..add(18737)
+ ..add(18738)
+ ..add(18739)
+ ..add(18740)
+ ..add(18741)
+ ..add(18742)
+ ..add(18743)
+ ..add(18744)
+ ..add(18745)
+ ..add(18746)
+ ..add(18747)
+ ..add(18748)
+ ..add(18749)
+ ..add(18750)
+ ..add(18751)
+ ..add(18752)
+ ..add(18753)
+ ..add(18754)
+ ..add(18755)
+ ..add(18756)
+ ..add(18757)
+ ..add(18758)
+ ..add(18759)
+ ..add(18760)
+ ..add(18761)
+ ..add(18762)
+ ..add(18763)
+ ..add(18764)
+ ..add(18765)
+ ..add(18766)
+ ..add(18767)
+ ..add(18768)
+ ..add(18769)
+ ..add(18770)
+ ..add(18771)
+ ..add(18772)
+ ..add(18773)
+ ..add(18774)
+ ..add(18775)
+ ..add(18776)
+ ..add(18777)
+ ..add(18778)
+ ..add(18779)
+ ..add(18780)
+ ..add(18781)
+ ..add(18782)
+ ..add(18783)
+ ..add(18784)
+ ..add(18785)
+ ..add(18786)
+ ..add(18787)
+ ..add(18788)
+ ..add(18789)
+ ..add(18790)
+ ..add(18791)
+ ..add(18792)
+ ..add(18793)
+ ..add(18794)
+ ..add(18795)
+ ..add(18796)
+ ..add(18797)
+ ..add(18798)
+ ..add(18799)
+ ..add(18800)
+ ..add(18801)
+ ..add(18802)
+ ..add(18803)
+ ..add(18804)
+ ..add(18805)
+ ..add(18806)
+ ..add(18807)
+ ..add(18808)
+ ..add(18809)
+ ..add(18810)
+ ..add(18811)
+ ..add(18812)
+ ..add(18813)
+ ..add(18814)
+ ..add(18815)
+ ..add(18816)
+ ..add(18817)
+ ..add(18818)
+ ..add(18819)
+ ..add(18820)
+ ..add(18821)
+ ..add(18822)
+ ..add(18823)
+ ..add(18824)
+ ..add(18825)
+ ..add(18826)
+ ..add(18827)
+ ..add(18828)
+ ..add(18829)
+ ..add(18830)
+ ..add(18831)
+ ..add(18832)
+ ..add(18833)
+ ..add(18834)
+ ..add(18835)
+ ..add(18836)
+ ..add(18837)
+ ..add(18838)
+ ..add(18839)
+ ..add(18840)
+ ..add(18841)
+ ..add(18842)
+ ..add(18843)
+ ..add(18844)
+ ..add(18845)
+ ..add(18846)
+ ..add(18847)
+ ..add(18848)
+ ..add(18849)
+ ..add(18850)
+ ..add(18851)
+ ..add(18852)
+ ..add(18853)
+ ..add(18854)
+ ..add(18855)
+ ..add(18856)
+ ..add(18857)
+ ..add(18858)
+ ..add(18859)
+ ..add(18860)
+ ..add(18861)
+ ..add(18862)
+ ..add(18863)
+ ..add(18864)
+ ..add(18865)
+ ..add(18866)
+ ..add(18867)
+ ..add(18868)
+ ..add(18869)
+ ..add(18870)
+ ..add(18871)
+ ..add(18872)
+ ..add(18873)
+ ..add(18874)
+ ..add(18875)
+ ..add(18876)
+ ..add(18877)
+ ..add(18878)
+ ..add(18879)
+ ..add(18880)
+ ..add(18881)
+ ..add(18882)
+ ..add(18883)
+ ..add(18884)
+ ..add(18885)
+ ..add(18886)
+ ..add(18887)
+ ..add(18888)
+ ..add(18889)
+ ..add(18890)
+ ..add(18891)
+ ..add(18892)
+ ..add(18893)
+ ..add(18894)
+ ..add(18895)
+ ..add(18896)
+ ..add(18897)
+ ..add(18898)
+ ..add(18899)
+ ..add(18900)
+ ..add(18901)
+ ..add(18902)
+ ..add(18903)
+ ..add(18904)
+ ..add(18905)
+ ..add(18906)
+ ..add(18907)
+ ..add(18908)
+ ..add(18909)
+ ..add(18910)
+ ..add(18911)
+ ..add(18912)
+ ..add(18913)
+ ..add(18914)
+ ..add(18915)
+ ..add(18916)
+ ..add(18917)
+ ..add(18918)
+ ..add(18919)
+ ..add(18920)
+ ..add(18921)
+ ..add(18922)
+ ..add(18923)
+ ..add(18924)
+ ..add(18925)
+ ..add(18926)
+ ..add(18927)
+ ..add(18928)
+ ..add(18929)
+ ..add(18930)
+ ..add(18931)
+ ..add(18932)
+ ..add(18933)
+ ..add(18934)
+ ..add(18935)
+ ..add(18936)
+ ..add(18937)
+ ..add(18938)
+ ..add(18939)
+ ..add(18940)
+ ..add(18941)
+ ..add(18942)
+ ..add(18943)
+ ..add(18944)
+ ..add(18945)
+ ..add(18946)
+ ..add(18947)
+ ..add(18948)
+ ..add(18949)
+ ..add(18950)
+ ..add(18951)
+ ..add(18952)
+ ..add(18953)
+ ..add(18954)
+ ..add(18955)
+ ..add(18956)
+ ..add(18957)
+ ..add(18958)
+ ..add(18959)
+ ..add(18960)
+ ..add(18961)
+ ..add(18962)
+ ..add(18963)
+ ..add(18964)
+ ..add(18965)
+ ..add(18966)
+ ..add(18967)
+ ..add(18968)
+ ..add(18969)
+ ..add(18970)
+ ..add(18971)
+ ..add(18972)
+ ..add(18973)
+ ..add(18974)
+ ..add(18975)
+ ..add(18976)
+ ..add(18977)
+ ..add(18978)
+ ..add(18979)
+ ..add(18980)
+ ..add(18981)
+ ..add(18982)
+ ..add(18983)
+ ..add(18984)
+ ..add(18985)
+ ..add(18986)
+ ..add(18987)
+ ..add(18988)
+ ..add(18989)
+ ..add(18990)
+ ..add(18991)
+ ..add(18992)
+ ..add(18993)
+ ..add(18994)
+ ..add(18995)
+ ..add(18996)
+ ..add(18997)
+ ..add(18998)
+ ..add(18999)
+ ..add(19000)
+ ..add(19001)
+ ..add(19002)
+ ..add(19003)
+ ..add(19004)
+ ..add(19005)
+ ..add(19006)
+ ..add(19007)
+ ..add(19008)
+ ..add(19009)
+ ..add(19010)
+ ..add(19011)
+ ..add(19012)
+ ..add(19013)
+ ..add(19014)
+ ..add(19015)
+ ..add(19016)
+ ..add(19017)
+ ..add(19018)
+ ..add(19019)
+ ..add(19020)
+ ..add(19021)
+ ..add(19022)
+ ..add(19023)
+ ..add(19024)
+ ..add(19025)
+ ..add(19026)
+ ..add(19027)
+ ..add(19028)
+ ..add(19029)
+ ..add(19030)
+ ..add(19031)
+ ..add(19032)
+ ..add(19033)
+ ..add(19034)
+ ..add(19035)
+ ..add(19036)
+ ..add(19037)
+ ..add(19038)
+ ..add(19039)
+ ..add(19040)
+ ..add(19041)
+ ..add(19042)
+ ..add(19043)
+ ..add(19044)
+ ..add(19045)
+ ..add(19046)
+ ..add(19047)
+ ..add(19048)
+ ..add(19049)
+ ..add(19050)
+ ..add(19051)
+ ..add(19052)
+ ..add(19053)
+ ..add(19054)
+ ..add(19055)
+ ..add(19056)
+ ..add(19057)
+ ..add(19058)
+ ..add(19059)
+ ..add(19060)
+ ..add(19061)
+ ..add(19062)
+ ..add(19063)
+ ..add(19064)
+ ..add(19065)
+ ..add(19066)
+ ..add(19067)
+ ..add(19068)
+ ..add(19069)
+ ..add(19070)
+ ..add(19071)
+ ..add(19072)
+ ..add(19073)
+ ..add(19074)
+ ..add(19075)
+ ..add(19076)
+ ..add(19077)
+ ..add(19078)
+ ..add(19079)
+ ..add(19080)
+ ..add(19081)
+ ..add(19082)
+ ..add(19083)
+ ..add(19084)
+ ..add(19085)
+ ..add(19086)
+ ..add(19087)
+ ..add(19088)
+ ..add(19089)
+ ..add(19090)
+ ..add(19091)
+ ..add(19092)
+ ..add(19093)
+ ..add(19094)
+ ..add(19095)
+ ..add(19096)
+ ..add(19097)
+ ..add(19098)
+ ..add(19099)
+ ..add(19100)
+ ..add(19101)
+ ..add(19102)
+ ..add(19103)
+ ..add(19104)
+ ..add(19105)
+ ..add(19106)
+ ..add(19107)
+ ..add(19108)
+ ..add(19109)
+ ..add(19110)
+ ..add(19111)
+ ..add(19112)
+ ..add(19113)
+ ..add(19114)
+ ..add(19115)
+ ..add(19116)
+ ..add(19117)
+ ..add(19118)
+ ..add(19119)
+ ..add(19120)
+ ..add(19121)
+ ..add(19122)
+ ..add(19123)
+ ..add(19124)
+ ..add(19125)
+ ..add(19126)
+ ..add(19127)
+ ..add(19128)
+ ..add(19129)
+ ..add(19130)
+ ..add(19131)
+ ..add(19132)
+ ..add(19133)
+ ..add(19134)
+ ..add(19135)
+ ..add(19136)
+ ..add(19137)
+ ..add(19138)
+ ..add(19139)
+ ..add(19140)
+ ..add(19141)
+ ..add(19142)
+ ..add(19143)
+ ..add(19144)
+ ..add(19145)
+ ..add(19146)
+ ..add(19147)
+ ..add(19148)
+ ..add(19149)
+ ..add(19150)
+ ..add(19151)
+ ..add(19152)
+ ..add(19153)
+ ..add(19154)
+ ..add(19155)
+ ..add(19156)
+ ..add(19157)
+ ..add(19158)
+ ..add(19159)
+ ..add(19160)
+ ..add(19161)
+ ..add(19162)
+ ..add(19163)
+ ..add(19164)
+ ..add(19165)
+ ..add(19166)
+ ..add(19167)
+ ..add(19168)
+ ..add(19169)
+ ..add(19170)
+ ..add(19171)
+ ..add(19172)
+ ..add(19173)
+ ..add(19174)
+ ..add(19175)
+ ..add(19176)
+ ..add(19177)
+ ..add(19178)
+ ..add(19179)
+ ..add(19180)
+ ..add(19181)
+ ..add(19182)
+ ..add(19183)
+ ..add(19184)
+ ..add(19185)
+ ..add(19186)
+ ..add(19187)
+ ..add(19188)
+ ..add(19189)
+ ..add(19190)
+ ..add(19191)
+ ..add(19192)
+ ..add(19193)
+ ..add(19194)
+ ..add(19195)
+ ..add(19196)
+ ..add(19197)
+ ..add(19198)
+ ..add(19199)
+ ..add(19200)
+ ..add(19201)
+ ..add(19202)
+ ..add(19203)
+ ..add(19204)
+ ..add(19205)
+ ..add(19206)
+ ..add(19207)
+ ..add(19208)
+ ..add(19209)
+ ..add(19210)
+ ..add(19211)
+ ..add(19212)
+ ..add(19213)
+ ..add(19214)
+ ..add(19215)
+ ..add(19216)
+ ..add(19217)
+ ..add(19218)
+ ..add(19219)
+ ..add(19220)
+ ..add(19221)
+ ..add(19222)
+ ..add(19223)
+ ..add(19224)
+ ..add(19225)
+ ..add(19226)
+ ..add(19227)
+ ..add(19228)
+ ..add(19229)
+ ..add(19230)
+ ..add(19231)
+ ..add(19232)
+ ..add(19233)
+ ..add(19234)
+ ..add(19235)
+ ..add(19236)
+ ..add(19237)
+ ..add(19238)
+ ..add(19239)
+ ..add(19240)
+ ..add(19241)
+ ..add(19242)
+ ..add(19243)
+ ..add(19244)
+ ..add(19245)
+ ..add(19246)
+ ..add(19247)
+ ..add(19248)
+ ..add(19249)
+ ..add(19250)
+ ..add(19251)
+ ..add(19252)
+ ..add(19253)
+ ..add(19254)
+ ..add(19255)
+ ..add(19256)
+ ..add(19257)
+ ..add(19258)
+ ..add(19259)
+ ..add(19260)
+ ..add(19261)
+ ..add(19262)
+ ..add(19263)
+ ..add(19264)
+ ..add(19265)
+ ..add(19266)
+ ..add(19267)
+ ..add(19268)
+ ..add(19269)
+ ..add(19270)
+ ..add(19271)
+ ..add(19272)
+ ..add(19273)
+ ..add(19274)
+ ..add(19275)
+ ..add(19276)
+ ..add(19277)
+ ..add(19278)
+ ..add(19279)
+ ..add(19280)
+ ..add(19281)
+ ..add(19282)
+ ..add(19283)
+ ..add(19284)
+ ..add(19285)
+ ..add(19286)
+ ..add(19287)
+ ..add(19288)
+ ..add(19289)
+ ..add(19290)
+ ..add(19291)
+ ..add(19292)
+ ..add(19293)
+ ..add(19294)
+ ..add(19295)
+ ..add(19296)
+ ..add(19297)
+ ..add(19298)
+ ..add(19299)
+ ..add(19300)
+ ..add(19301)
+ ..add(19302)
+ ..add(19303)
+ ..add(19304)
+ ..add(19305)
+ ..add(19306)
+ ..add(19307)
+ ..add(19308)
+ ..add(19309)
+ ..add(19310)
+ ..add(19311)
+ ..add(19312)
+ ..add(19313)
+ ..add(19314)
+ ..add(19315)
+ ..add(19316)
+ ..add(19317)
+ ..add(19318)
+ ..add(19319)
+ ..add(19320)
+ ..add(19321)
+ ..add(19322)
+ ..add(19323)
+ ..add(19324)
+ ..add(19325)
+ ..add(19326)
+ ..add(19327)
+ ..add(19328)
+ ..add(19329)
+ ..add(19330)
+ ..add(19331)
+ ..add(19332)
+ ..add(19333)
+ ..add(19334)
+ ..add(19335)
+ ..add(19336)
+ ..add(19337)
+ ..add(19338)
+ ..add(19339)
+ ..add(19340)
+ ..add(19341)
+ ..add(19342)
+ ..add(19343)
+ ..add(19344)
+ ..add(19345)
+ ..add(19346)
+ ..add(19347)
+ ..add(19348)
+ ..add(19349)
+ ..add(19350)
+ ..add(19351)
+ ..add(19352)
+ ..add(19353)
+ ..add(19354)
+ ..add(19355)
+ ..add(19356)
+ ..add(19357)
+ ..add(19358)
+ ..add(19359)
+ ..add(19360)
+ ..add(19361)
+ ..add(19362)
+ ..add(19363)
+ ..add(19364)
+ ..add(19365)
+ ..add(19366)
+ ..add(19367)
+ ..add(19368)
+ ..add(19369)
+ ..add(19370)
+ ..add(19371)
+ ..add(19372)
+ ..add(19373)
+ ..add(19374)
+ ..add(19375)
+ ..add(19376)
+ ..add(19377)
+ ..add(19378)
+ ..add(19379)
+ ..add(19380)
+ ..add(19381)
+ ..add(19382)
+ ..add(19383)
+ ..add(19384)
+ ..add(19385)
+ ..add(19386)
+ ..add(19387)
+ ..add(19388)
+ ..add(19389)
+ ..add(19390)
+ ..add(19391)
+ ..add(19392)
+ ..add(19393)
+ ..add(19394)
+ ..add(19395)
+ ..add(19396)
+ ..add(19397)
+ ..add(19398)
+ ..add(19399)
+ ..add(19400)
+ ..add(19401)
+ ..add(19402)
+ ..add(19403)
+ ..add(19404)
+ ..add(19405)
+ ..add(19406)
+ ..add(19407)
+ ..add(19408)
+ ..add(19409)
+ ..add(19410)
+ ..add(19411)
+ ..add(19412)
+ ..add(19413)
+ ..add(19414)
+ ..add(19415)
+ ..add(19416)
+ ..add(19417)
+ ..add(19418)
+ ..add(19419)
+ ..add(19420)
+ ..add(19421)
+ ..add(19422)
+ ..add(19423)
+ ..add(19424)
+ ..add(19425)
+ ..add(19426)
+ ..add(19427)
+ ..add(19428)
+ ..add(19429)
+ ..add(19430)
+ ..add(19431)
+ ..add(19432)
+ ..add(19433)
+ ..add(19434)
+ ..add(19435)
+ ..add(19436)
+ ..add(19437)
+ ..add(19438)
+ ..add(19439)
+ ..add(19440)
+ ..add(19441)
+ ..add(19442)
+ ..add(19443)
+ ..add(19444)
+ ..add(19445)
+ ..add(19446)
+ ..add(19447)
+ ..add(19448)
+ ..add(19449)
+ ..add(19450)
+ ..add(19451)
+ ..add(19452)
+ ..add(19453)
+ ..add(19454)
+ ..add(19455)
+ ..add(19456)
+ ..add(19457)
+ ..add(19458)
+ ..add(19459)
+ ..add(19460)
+ ..add(19461)
+ ..add(19462)
+ ..add(19463)
+ ..add(19464)
+ ..add(19465)
+ ..add(19466)
+ ..add(19467)
+ ..add(19468)
+ ..add(19469)
+ ..add(19470)
+ ..add(19471)
+ ..add(19472)
+ ..add(19473)
+ ..add(19474)
+ ..add(19475)
+ ..add(19476)
+ ..add(19477)
+ ..add(19478)
+ ..add(19479)
+ ..add(19480)
+ ..add(19481)
+ ..add(19482)
+ ..add(19483)
+ ..add(19484)
+ ..add(19485)
+ ..add(19486)
+ ..add(19487)
+ ..add(19488)
+ ..add(19489)
+ ..add(19490)
+ ..add(19491)
+ ..add(19492)
+ ..add(19493)
+ ..add(19494)
+ ..add(19495)
+ ..add(19496)
+ ..add(19497)
+ ..add(19498)
+ ..add(19499)
+ ..add(19500)
+ ..add(19501)
+ ..add(19502)
+ ..add(19503)
+ ..add(19504)
+ ..add(19505)
+ ..add(19506)
+ ..add(19507)
+ ..add(19508)
+ ..add(19509)
+ ..add(19510)
+ ..add(19511)
+ ..add(19512)
+ ..add(19513)
+ ..add(19514)
+ ..add(19515)
+ ..add(19516)
+ ..add(19517)
+ ..add(19518)
+ ..add(19519)
+ ..add(19520)
+ ..add(19521)
+ ..add(19522)
+ ..add(19523)
+ ..add(19524)
+ ..add(19525)
+ ..add(19526)
+ ..add(19527)
+ ..add(19528)
+ ..add(19529)
+ ..add(19530)
+ ..add(19531)
+ ..add(19532)
+ ..add(19533)
+ ..add(19534)
+ ..add(19535)
+ ..add(19536)
+ ..add(19537)
+ ..add(19538)
+ ..add(19539)
+ ..add(19540)
+ ..add(19541)
+ ..add(19542)
+ ..add(19543)
+ ..add(19544)
+ ..add(19545)
+ ..add(19546)
+ ..add(19547)
+ ..add(19548)
+ ..add(19549)
+ ..add(19550)
+ ..add(19551)
+ ..add(19552)
+ ..add(19553)
+ ..add(19554)
+ ..add(19555)
+ ..add(19556)
+ ..add(19557)
+ ..add(19558)
+ ..add(19559)
+ ..add(19560)
+ ..add(19561)
+ ..add(19562)
+ ..add(19563)
+ ..add(19564)
+ ..add(19565)
+ ..add(19566)
+ ..add(19567)
+ ..add(19568)
+ ..add(19569)
+ ..add(19570)
+ ..add(19571)
+ ..add(19572)
+ ..add(19573)
+ ..add(19574)
+ ..add(19575)
+ ..add(19576)
+ ..add(19577)
+ ..add(19578)
+ ..add(19579)
+ ..add(19580)
+ ..add(19581)
+ ..add(19582)
+ ..add(19583)
+ ..add(19584)
+ ..add(19585)
+ ..add(19586)
+ ..add(19587)
+ ..add(19588)
+ ..add(19589)
+ ..add(19590)
+ ..add(19591)
+ ..add(19592)
+ ..add(19593)
+ ..add(19594)
+ ..add(19595)
+ ..add(19596)
+ ..add(19597)
+ ..add(19598)
+ ..add(19599)
+ ..add(19600)
+ ..add(19601)
+ ..add(19602)
+ ..add(19603)
+ ..add(19604)
+ ..add(19605)
+ ..add(19606)
+ ..add(19607)
+ ..add(19608)
+ ..add(19609)
+ ..add(19610)
+ ..add(19611)
+ ..add(19612)
+ ..add(19613)
+ ..add(19614)
+ ..add(19615)
+ ..add(19616)
+ ..add(19617)
+ ..add(19618)
+ ..add(19619)
+ ..add(19620)
+ ..add(19621)
+ ..add(19622)
+ ..add(19623)
+ ..add(19624)
+ ..add(19625)
+ ..add(19626)
+ ..add(19627)
+ ..add(19628)
+ ..add(19629)
+ ..add(19630)
+ ..add(19631)
+ ..add(19632)
+ ..add(19633)
+ ..add(19634)
+ ..add(19635)
+ ..add(19636)
+ ..add(19637)
+ ..add(19638)
+ ..add(19639)
+ ..add(19640)
+ ..add(19641)
+ ..add(19642)
+ ..add(19643)
+ ..add(19644)
+ ..add(19645)
+ ..add(19646)
+ ..add(19647)
+ ..add(19648)
+ ..add(19649)
+ ..add(19650)
+ ..add(19651)
+ ..add(19652)
+ ..add(19653)
+ ..add(19654)
+ ..add(19655)
+ ..add(19656)
+ ..add(19657)
+ ..add(19658)
+ ..add(19659)
+ ..add(19660)
+ ..add(19661)
+ ..add(19662)
+ ..add(19663)
+ ..add(19664)
+ ..add(19665)
+ ..add(19666)
+ ..add(19667)
+ ..add(19668)
+ ..add(19669)
+ ..add(19670)
+ ..add(19671)
+ ..add(19672)
+ ..add(19673)
+ ..add(19674)
+ ..add(19675)
+ ..add(19676)
+ ..add(19677)
+ ..add(19678)
+ ..add(19679)
+ ..add(19680)
+ ..add(19681)
+ ..add(19682)
+ ..add(19683)
+ ..add(19684)
+ ..add(19685)
+ ..add(19686)
+ ..add(19687)
+ ..add(19688)
+ ..add(19689)
+ ..add(19690)
+ ..add(19691)
+ ..add(19692)
+ ..add(19693)
+ ..add(19694)
+ ..add(19695)
+ ..add(19696)
+ ..add(19697)
+ ..add(19698)
+ ..add(19699)
+ ..add(19700)
+ ..add(19701)
+ ..add(19702)
+ ..add(19703)
+ ..add(19704)
+ ..add(19705)
+ ..add(19706)
+ ..add(19707)
+ ..add(19708)
+ ..add(19709)
+ ..add(19710)
+ ..add(19711)
+ ..add(19712)
+ ..add(19713)
+ ..add(19714)
+ ..add(19715)
+ ..add(19716)
+ ..add(19717)
+ ..add(19718)
+ ..add(19719)
+ ..add(19720)
+ ..add(19721)
+ ..add(19722)
+ ..add(19723)
+ ..add(19724)
+ ..add(19725)
+ ..add(19726)
+ ..add(19727)
+ ..add(19728)
+ ..add(19729)
+ ..add(19730)
+ ..add(19731)
+ ..add(19732)
+ ..add(19733)
+ ..add(19734)
+ ..add(19735)
+ ..add(19736)
+ ..add(19737)
+ ..add(19738)
+ ..add(19739)
+ ..add(19740)
+ ..add(19741)
+ ..add(19742)
+ ..add(19743)
+ ..add(19744)
+ ..add(19745)
+ ..add(19746)
+ ..add(19747)
+ ..add(19748)
+ ..add(19749)
+ ..add(19750)
+ ..add(19751)
+ ..add(19752)
+ ..add(19753)
+ ..add(19754)
+ ..add(19755)
+ ..add(19756)
+ ..add(19757)
+ ..add(19758)
+ ..add(19759)
+ ..add(19760)
+ ..add(19761)
+ ..add(19762)
+ ..add(19763)
+ ..add(19764)
+ ..add(19765)
+ ..add(19766)
+ ..add(19767)
+ ..add(19768)
+ ..add(19769)
+ ..add(19770)
+ ..add(19771)
+ ..add(19772)
+ ..add(19773)
+ ..add(19774)
+ ..add(19775)
+ ..add(19776)
+ ..add(19777)
+ ..add(19778)
+ ..add(19779)
+ ..add(19780)
+ ..add(19781)
+ ..add(19782)
+ ..add(19783)
+ ..add(19784)
+ ..add(19785)
+ ..add(19786)
+ ..add(19787)
+ ..add(19788)
+ ..add(19789)
+ ..add(19790)
+ ..add(19791)
+ ..add(19792)
+ ..add(19793)
+ ..add(19794)
+ ..add(19795)
+ ..add(19796)
+ ..add(19797)
+ ..add(19798)
+ ..add(19799)
+ ..add(19800)
+ ..add(19801)
+ ..add(19802)
+ ..add(19803)
+ ..add(19804)
+ ..add(19805)
+ ..add(19806)
+ ..add(19807)
+ ..add(19808)
+ ..add(19809)
+ ..add(19810)
+ ..add(19811)
+ ..add(19812)
+ ..add(19813)
+ ..add(19814)
+ ..add(19815)
+ ..add(19816)
+ ..add(19817)
+ ..add(19818)
+ ..add(19819)
+ ..add(19820)
+ ..add(19821)
+ ..add(19822)
+ ..add(19823)
+ ..add(19824)
+ ..add(19825)
+ ..add(19826)
+ ..add(19827)
+ ..add(19828)
+ ..add(19829)
+ ..add(19830)
+ ..add(19831)
+ ..add(19832)
+ ..add(19833)
+ ..add(19834)
+ ..add(19835)
+ ..add(19836)
+ ..add(19837)
+ ..add(19838)
+ ..add(19839)
+ ..add(19840)
+ ..add(19841)
+ ..add(19842)
+ ..add(19843)
+ ..add(19844)
+ ..add(19845)
+ ..add(19846)
+ ..add(19847)
+ ..add(19848)
+ ..add(19849)
+ ..add(19850)
+ ..add(19851)
+ ..add(19852)
+ ..add(19853)
+ ..add(19854)
+ ..add(19855)
+ ..add(19856)
+ ..add(19857)
+ ..add(19858)
+ ..add(19859)
+ ..add(19860)
+ ..add(19861)
+ ..add(19862)
+ ..add(19863)
+ ..add(19864)
+ ..add(19865)
+ ..add(19866)
+ ..add(19867)
+ ..add(19868)
+ ..add(19869)
+ ..add(19870)
+ ..add(19871)
+ ..add(19872)
+ ..add(19873)
+ ..add(19874)
+ ..add(19875)
+ ..add(19876)
+ ..add(19877)
+ ..add(19878)
+ ..add(19879)
+ ..add(19880)
+ ..add(19881)
+ ..add(19882)
+ ..add(19883)
+ ..add(19884)
+ ..add(19885)
+ ..add(19886)
+ ..add(19887)
+ ..add(19888)
+ ..add(19889)
+ ..add(19890)
+ ..add(19891)
+ ..add(19892)
+ ..add(19893)
+ ..add(19894)
+ ..add(19895)
+ ..add(19896)
+ ..add(19897)
+ ..add(19898)
+ ..add(19899)
+ ..add(19900)
+ ..add(19901)
+ ..add(19902)
+ ..add(19903)
+ ..add(19904)
+ ..add(19905)
+ ..add(19906)
+ ..add(19907)
+ ..add(19908)
+ ..add(19909)
+ ..add(19910)
+ ..add(19911)
+ ..add(19912)
+ ..add(19913)
+ ..add(19914)
+ ..add(19915)
+ ..add(19916)
+ ..add(19917)
+ ..add(19918)
+ ..add(19919)
+ ..add(19920)
+ ..add(19921)
+ ..add(19922)
+ ..add(19923)
+ ..add(19924)
+ ..add(19925)
+ ..add(19926)
+ ..add(19927)
+ ..add(19928)
+ ..add(19929)
+ ..add(19930)
+ ..add(19931)
+ ..add(19932)
+ ..add(19933)
+ ..add(19934)
+ ..add(19935)
+ ..add(19936)
+ ..add(19937)
+ ..add(19938)
+ ..add(19939)
+ ..add(19940)
+ ..add(19941)
+ ..add(19942)
+ ..add(19943)
+ ..add(19944)
+ ..add(19945)
+ ..add(19946)
+ ..add(19947)
+ ..add(19948)
+ ..add(19949)
+ ..add(19950)
+ ..add(19951)
+ ..add(19952)
+ ..add(19953)
+ ..add(19954)
+ ..add(19955)
+ ..add(19956)
+ ..add(19957)
+ ..add(19958)
+ ..add(19959)
+ ..add(19960)
+ ..add(19961)
+ ..add(19962)
+ ..add(19963)
+ ..add(19964)
+ ..add(19965)
+ ..add(19966)
+ ..add(19967)
+ ..add(19968)
+ ..add(19969)
+ ..add(19970)
+ ..add(19971)
+ ..add(19972)
+ ..add(19973)
+ ..add(19974)
+ ..add(19975)
+ ..add(19976)
+ ..add(19977)
+ ..add(19978)
+ ..add(19979)
+ ..add(19980)
+ ..add(19981)
+ ..add(19982)
+ ..add(19983)
+ ..add(19984)
+ ..add(19985)
+ ..add(19986)
+ ..add(19987)
+ ..add(19988)
+ ..add(19989)
+ ..add(19990)
+ ..add(19991)
+ ..add(19992)
+ ..add(19993)
+ ..add(19994)
+ ..add(19995)
+ ..add(19996)
+ ..add(19997)
+ ..add(19998)
+ ..add(19999);
+
+ Expect.equals(ints.length, 20000);
+ for (int i = 0; i < ints.length; i++) {
+ Expect.equals(ints[i], i);
+ }
+}
diff --git a/tests/language_2/unsorted/disassemble_test.dart b/tests/language_2/unsorted/disassemble_test.dart
index 7bbc32c..bc3b032 100644
--- a/tests/language_2/unsorted/disassemble_test.dart
+++ b/tests/language_2/unsorted/disassemble_test.dart
@@ -1,9 +1,9 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Dart test program for testing isolate communication with
-// typed objects.
+
// VMOptions=--disassemble
+// VMOptions=--disassemble --always_generate_trampolines_for_testing
// Tests proper object recognition in disassembler.
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index cd733a9..e005a49 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -41,8 +41,11 @@
[ $runtime == chrome && $system == macos ]
convert/streamed_conversion_utf8_encode_test: SkipSlow # Times out. Issue 22050
-html/canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
-html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Skip # Times out. Please triage this failure.
+html/canvasrendering/arc_test: Skip # Issue 42048
+html/canvasrendering/draw_image_canvas_element_test: Skip # Issue 42048
+html/canvasrendering/fill_text_test: Skip # Issue 42048
+html/canvasrendering/image_element_test: Skip # Issue 42048
+html/canvasrendering/pixel_manipulation_test: Skip # Issue 42048
html/request_animation_frame_test: Skip # Times out. Issue 22167
html/transition_event_test: Skip # Times out. Issue 22167
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 3365351..c21cc4c 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -41,8 +41,11 @@
[ $runtime == chrome && $system == macos ]
convert/streamed_conversion_utf8_encode_test: SkipSlow # Times out. Issue 22050
-html/canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
-html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Skip # Times out. Please triage this failure.
+html/canvasrendering/arc_test: Skip # Issue 42048
+html/canvasrendering/draw_image_canvas_element_test: Skip # Issue 42048
+html/canvasrendering/fill_text_test: Skip # Issue 42048
+html/canvasrendering/image_element_test: Skip # Issue 42048
+html/canvasrendering/pixel_manipulation_test: Skip # Issue 42048
html/request_animation_frame_test: Skip # Times out. Issue 22167
html/transition_event_test: Skip # Times out. Issue 22167
diff --git a/tests/standalone_2/dwarf_stack_trace_test.dart b/tests/standalone_2/dwarf_stack_trace_test.dart
index bed8cfa..8af577b 100644
--- a/tests/standalone_2/dwarf_stack_trace_test.dart
+++ b/tests/standalone_2/dwarf_stack_trace_test.dart
@@ -66,6 +66,17 @@
final virtualAddresses =
pcOffsets.map((o) => dwarf.virtualAddressOf(o)).toList();
+ // Some double-checks using other information in the non-symbolic stack trace.
+ final dsoBase = dsoBaseAddresses(rawLines).single;
+ final absolutes = absoluteAddresses(rawLines);
+ final relocatedAddresses = absolutes.map((a) => a - dsoBase);
+ final explicits = explicitVirtualAddresses(rawLines);
+ Expect.deepEquals(relocatedAddresses, virtualAddresses);
+ // Explicits will be empty if not generating ELF snapshots directly.
+ if (explicits.isNotEmpty) {
+ Expect.deepEquals(explicits, virtualAddresses);
+ }
+
final externalFramesInfo = <List<CallInfo>>[];
final allFramesInfo = <List<CallInfo>>[];
@@ -247,3 +258,27 @@
}
return ret;
}
+
+Iterable<int> parseUsingAddressRegExp(RegExp re, Iterable<String> lines) sync* {
+ for (final line in lines) {
+ final match = re.firstMatch(line);
+ if (match != null) {
+ yield int.parse(match.group(1), radix: 16);
+ }
+ }
+}
+
+final _absRE = RegExp(r'abs ([a-f\d]+)');
+
+Iterable<int> absoluteAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_absRE, lines);
+
+final _virtRE = RegExp(r'virt ([a-f\d]+)');
+
+Iterable<int> explicitVirtualAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_virtRE, lines);
+
+final _dsoBaseRE = RegExp(r'isolate_dso_base: ([a-f\d]+)');
+
+Iterable<int> dsoBaseAddresses(Iterable<String> lines) =>
+ parseUsingAddressRegExp(_dsoBaseRE, lines);
diff --git a/tests/standalone_2/regress_41329_absolute_test.dart b/tests/standalone_2/regress_41329_absolute_test.dart
index 5673b99..cc2a402 100644
--- a/tests/standalone_2/regress_41329_absolute_test.dart
+++ b/tests/standalone_2/regress_41329_absolute_test.dart
@@ -29,9 +29,6 @@
final link2 = Link('dart')..createSync(linkLocation, recursive: true);
final path = Uri.parse(link2.absolute.path).path;
Directory.current = origDir;
- final result = await Process.run('${path}',
- [p.relative(Platform.script.resolve('regress_41329_helper.dart').path)]);
- Expect.equals(result.stdout, '');
- Expect.equals(result.stderr, '');
- Expect.equals(result.exitCode, 42);
+ final result = await Process.run('${path}', ['help']);
+ Expect.equals(result.exitCode, 0);
}
diff --git a/tests/standalone_2/regress_41329_helper.dart b/tests/standalone_2/regress_41329_helper.dart
deleted file mode 100644
index f6f82dd..0000000
--- a/tests/standalone_2/regress_41329_helper.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-main() {
- exitCode = 42;
-}
diff --git a/tests/standalone_2/regress_41329_relative_test.dart b/tests/standalone_2/regress_41329_relative_test.dart
index 5673b99..cc2a402 100644
--- a/tests/standalone_2/regress_41329_relative_test.dart
+++ b/tests/standalone_2/regress_41329_relative_test.dart
@@ -29,9 +29,6 @@
final link2 = Link('dart')..createSync(linkLocation, recursive: true);
final path = Uri.parse(link2.absolute.path).path;
Directory.current = origDir;
- final result = await Process.run('${path}',
- [p.relative(Platform.script.resolve('regress_41329_helper.dart').path)]);
- Expect.equals(result.stdout, '');
- Expect.equals(result.stderr, '');
- Expect.equals(result.exitCode, 42);
+ final result = await Process.run('${path}', ['help']);
+ Expect.equals(result.exitCode, 0);
}
diff --git a/tools/VERSION b/tools/VERSION
index 4756f9a..996e1e0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 9
PATCH 0
-PRERELEASE 11
+PRERELEASE 12
PRERELEASE_PATCH 0
ABI_VERSION 34
OLDEST_SUPPORTED_ABI_VERSION 34
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 18c86c5..6b762c2 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1,6 +1,6 @@
{
"global": {
- "chrome": "76",
+ "chrome": "81",
"firefox": "67"
},
"branches": [
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 6c50302..219c48e 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -182,13 +182,9 @@
group("dartdevc_test_kernel_pkg") {
deps = [
":async_helper_js",
- ":collection_js",
":expect_js",
":js_js",
- ":matcher_js",
":meta_js",
- ":path_js",
- ":stack_trace_js",
]
}
@@ -266,10 +262,6 @@
package = "async_helper"
}
-dartdevc_kernel_compile("collection_js") {
- package = "collection"
-}
-
dartdevc_kernel_compile("expect_js") {
package = "expect"
extra_libraries = [ "minitest" ]
@@ -280,24 +272,10 @@
extra_libraries = [ "js_util" ]
}
-dartdevc_kernel_compile("matcher_js") {
- package = "matcher"
- package_dependencies = [ "stack_trace" ]
-}
-
dartdevc_kernel_compile("meta_js") {
package = "meta"
}
-dartdevc_kernel_compile("path_js") {
- package = "path"
-}
-
-dartdevc_kernel_compile("stack_trace_js") {
- package = "stack_trace"
- package_dependencies = [ "path" ]
-}
-
compile_platform("dartdevc_platform") {
single_root_scheme = "org-dartlang-sdk"
single_root_base = rebase_path("../../")