Version 2.10.0-77.0.dev
Merge commit '0967d19156acc5ca4fc1cf7dcc129d6c680f3696' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 052e071..c3ba326 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -178,7 +178,7 @@
"name": "csslib",
"rootUri": "../third_party/pkg/csslib",
"packageUri": "lib/",
- "languageVersion": "2.2"
+ "languageVersion": "2.10"
},
{
"name": "dart2js_info",
@@ -752,4 +752,4 @@
"languageVersion": "2.4"
}
]
-}
\ No newline at end of file
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f605320..9e6332c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
* Adds `Abort` method to class `HttpClientRequest`, which allows users
to cancel outgoing HTTP requests and stop following IO operations.
-* A validtion check is added to `path` of class `Cookie`. Having characters
+* A validation check is added to `path` of class `Cookie`. Having characters
ranging from 0x00 to 0x1f and 0x3b (";") will lead to a `FormatException`.
#### `dart:typed_data`
diff --git a/DEPS b/DEPS
index d6e2886..79c9692 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "d94e371b8aafa3f4b88821c63a5ef1f618c2124d",
+ "co19_rev": "12855e59cd7e031d076cc8cece9f5ee08e77ca8c",
"co19_2_rev": "e48b3090826cf40b8037648f19d211e8eab1b4b6",
# The internal benchmarks to use. See go/dart-benchmarks-internal
@@ -79,8 +79,8 @@
"collection_rev": "583693680fc067e34ca5b72503df25e8b80579f9",
"convert_rev": "c1b01f832835d3d8a06b0b246a361c0eaab35d3c",
"crypto_rev": "f7c48b334b1386bc5ab0f706fbcd6df8496a87fc",
- "csslib_rev": "451448a9ac03f87a8d0377fc0b411d8c388a6cb4",
- "dart2js_info_rev" : "94ba36cb77067f28b75a4212e77b810a2d7385e9",
+ "csslib_rev": "166d3e07eabc8283c6137cfde17fb25b8bb40080",
+ "dart2js_info_rev" : "0632a623b08e1f601c7eba99e0186a581ae799e9",
# Note: Updates to dart_style have to be coordinated with the infrastructure
# team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
index 5f87669..da4fc35 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/abstract_scanner.dart
@@ -1894,8 +1894,9 @@
codeUnits.add(next);
next = advance();
}
- appendToken(new StringToken.fromString(TokenType.IDENTIFIER,
- new String.fromCharCodes(codeUnits), charOffset));
+ appendToken(new StringToken.fromString(
+ TokenType.IDENTIFIER, new String.fromCharCodes(codeUnits), charOffset,
+ precedingComments: comments));
return next;
} else {
prependErrorToken(errorToken);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 3a0b9e7..a3860dc 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -25,7 +25,7 @@
void _addCommentRanges() {
var token = _unit.beginToken;
- do {
+ while (token != null) {
Token commentToken = token.precedingComments;
while (commentToken != null) {
HighlightRegionType highlightType;
@@ -44,8 +44,13 @@
}
commentToken = commentToken.next;
}
+ if (token.type == TokenType.EOF) {
+ // Only exit the loop *after* processing the EOF token as it may
+ // have preceeding comments.
+ break;
+ }
token = token.next;
- } while (token != null && token.type != TokenType.EOF);
+ }
}
void _addIdentifierRegion(SimpleIdentifier node) {
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index 3be6bae..2c677c7 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -25,7 +25,7 @@
void _addCommentRanges() {
var token = _unit.beginToken;
- do {
+ while (token != null) {
Token commentToken = token.precedingComments;
while (commentToken != null) {
HighlightRegionType highlightType;
@@ -44,8 +44,13 @@
}
commentToken = commentToken.next;
}
+ if (token.type == TokenType.EOF) {
+ // Only exit the loop *after* processing the EOF token as it may
+ // have preceeding comments.
+ break;
+ }
token = token.next;
- } while (token != null && token.type != TokenType.EOF);
+ }
}
void _addIdentifierRegion(SimpleIdentifier node) {
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index bb4ce51..f83015d 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -13,6 +13,7 @@
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';
import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_map_from_iterable_to_for_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_quotes.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
@@ -86,6 +87,8 @@
LintNames.prefer_equal_for_default_values:
ReplaceColonWithEquals.newInstance,
LintNames.prefer_final_fields: MakeFinal.newInstance,
+ LintNames.prefer_for_elements_to_map_fromIterable:
+ ConvertMapFromIterableToForLiteral.newInstance,
LintNames.prefer_generic_function_type_aliases:
ConvertToGenericFunctionSyntax.newInstance,
LintNames.prefer_if_elements_to_conditional_expressions:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 3a8456c..0235247 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -12,15 +12,15 @@
* Parameters:
* 0: the unsupported key
*/
- static const TransformSetErrorCode unsupportedKey = TransformSetErrorCode(
- 'unsupported_key', "The key '{0}' isn't supported.");
+ static const TransformSetErrorCode unsupportedKey =
+ TransformSetErrorCode('unsupportedKey', "The key '{0}' isn't supported.");
/**
* Parameters:
* 0: the message produced by the YAML parser
*/
static const TransformSetErrorCode yamlSyntaxError =
- TransformSetErrorCode('yaml_syntax_error', "{0}");
+ TransformSetErrorCode('yamlSyntaxError', "{0}");
/// Initialize a newly created error code.
const TransformSetErrorCode(String name, String message,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index 3a3af62..d6330c2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -43,12 +43,14 @@
/// [errorReporter].
TransformSetParser(this.errorReporter);
- /// Return the result of parsing the file [content] into a transform set.
+ /// Return the result of parsing the file [content] into a transform set, or
+ /// `null` if the content does not represent a valid transform set.
TransformSet parse(String content) {
assert(content != null);
var map = _parseYaml(content);
if (map == null) {
- return TransformSet();
+ // The error has already been reported.
+ return null;
}
return _translateTransformSet(map);
}
@@ -89,7 +91,8 @@
}
}
- /// Translate the [node] into a change.
+ /// Translate the [node] into a change. Return the resulting change, or `null`
+ /// if the [node] does not represent a valid change.
Change _translateChange(YamlNode node) {
if (node is YamlMap) {
var kind = _translateString(node.valueAt(_kindKey));
@@ -108,12 +111,22 @@
}
}
- /// Translate the [node] into an element descriptor.
+ /// Translate the [node] into an element descriptor. Return the resulting
+ /// descriptor, or `null` if the [node] does not represent a valid element
+ /// descriptor.
ElementDescriptor _translateElement(YamlNode node) {
if (node is YamlMap) {
var uris = _translateList(node.valueAt(_urisKey), _translateString);
+ if (uris == null) {
+ // The error has already been reported.
+ return null;
+ }
var components =
_translateList(node.valueAt(_componentsKey), _translateString);
+ if (components == null) {
+ // The error has already been reported.
+ return null;
+ }
return ElementDescriptor(libraryUris: uris, components: components);
} else if (node == null) {
// TODO(brianwilkerson) Report the missing YAML.
@@ -124,7 +137,8 @@
}
}
- /// Translate the [node] into an integer.
+ /// Translate the [node] into an integer. Return the resulting integer, or
+ /// `null` if the [node] does not represent a valid integer.
int _translateInteger(YamlNode node) {
if (node is YamlScalar) {
var value = node.value;
@@ -146,6 +160,9 @@
}
/// Translate the [node] into a list of objects using the [elementTranslator].
+ /// Return the resulting list, or `null` if the [node] does not represent a
+ /// valid list. If any of the elements of the list can't be translated, they
+ /// will be omitted from the list but the valid elements will be returned.
List<R> _translateList<R>(
YamlNode node, R Function(YamlNode) elementTranslator) {
if (node is YamlList) {
@@ -166,14 +183,19 @@
}
}
- /// Translate the [node] into a rename change.
+ /// Translate the [node] into a rename change. Return the resulting change, or
+ /// `null` if the [node] does not represent a valid rename change.
Change _translateRenameChange(YamlMap node) {
_reportUnsupportedKeys(node, const {_kindKey, _newNameKey});
var newName = _translateString(node.valueAt(_newNameKey));
+ if (newName == null) {
+ return null;
+ }
return Rename(newName: newName);
}
- /// Translate the [node] into a string.
+ /// Translate the [node] into a string. Return the resulting string, or `null`
+ /// if the [node] does not represent a valid string.
String _translateString(YamlNode node) {
if (node is YamlScalar) {
var value = node.value;
@@ -194,7 +216,8 @@
}
}
- /// Translate the [node] into a transform.
+ /// Translate the [node] into a transform. Return the resulting transform, or
+ /// `null` if the [node] does not represent a valid transform.
Transform _translateTransform(YamlNode node) {
if (node is YamlMap) {
_reportUnsupportedKeys(node, const {_changesKey, _elementKey, _titleKey});
@@ -202,6 +225,10 @@
var element = _translateElement(node.valueAt(_elementKey));
var changes =
_translateList<Change>(node.valueAt(_changesKey), _translateChange);
+ if (changes == null) {
+ // The error has already been reported.
+ return null;
+ }
return Transform(title: title, element: element, changes: changes);
} else if (node == null) {
// TODO(brianwilkerson) Report the missing YAML.
@@ -212,7 +239,8 @@
}
}
- /// Translate the [node] into a transform set.
+ /// Translate the [node] into a transform set. Return the resulting transform
+ /// set, or `null` if the [node] does not represent a valid transform set.
TransformSet _translateTransformSet(YamlNode node) {
if (node is YamlMap) {
_reportUnsupportedKeys(node, const {_transformsKey, _versionKey});
@@ -225,6 +253,10 @@
}
var transformations =
_translateList(node.valueAt(_transformsKey), _translateTransform);
+ if (transformations == null) {
+ // The error has already been reported.
+ return null;
+ }
for (var transform in transformations) {
set.addTransform(transform);
}
diff --git a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
index 1102320..5f3e70a0 100644
--- a/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights2_computer_test.dart
@@ -29,6 +29,21 @@
sourcePath = convertPath('/home/test/lib/test.dart');
}
+ Future<void> test_comment() async {
+ await _computeHighlights('''
+// A trailing comment
+''');
+ _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+ }
+
+ Future<void> test_comment_trailing() async {
+ await _computeHighlights('''
+class A {}
+// A trailing comment
+''');
+ _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+ }
+
Future<void> test_extension() async {
await _computeHighlights('''
extension E on String {}
@@ -62,13 +77,6 @@
_check(HighlightRegionType.KEYWORD, 'throw');
}
- Future<void> test_trailingComment() async {
- await _computeHighlights('''
-// A trailing comment
-''');
- _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
- }
-
void _check(HighlightRegionType expectedType, String expectedText) {
for (var region in highlights) {
if (region.type == expectedType) {
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
index d853b1e..854a638 100644
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
@@ -29,6 +29,21 @@
sourcePath = convertPath('/home/test/lib/test.dart');
}
+ Future<void> test_comment() async {
+ await _computeHighlights('''
+// A trailing comment
+''');
+ _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+ }
+
+ Future<void> test_comment_trailing() async {
+ await _computeHighlights('''
+class A {}
+// A trailing comment
+''');
+ _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
+ }
+
Future<void> test_extension() async {
await _computeHighlights('''
extension E on String {}
@@ -48,13 +63,6 @@
_check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
}
- Future<void> test_trailingComment() async {
- await _computeHighlights('''
-// A trailing comment
-''');
- _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
- }
-
void _check(HighlightRegionType expectedType, String expectedText) {
for (var region in highlights) {
if (region.type == expectedType) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart
new file mode 100644
index 0000000..151df66
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_map_from_iterable_to_for_literal_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToForElementTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToForElementTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_for_elements_to_map_fromIterable;
+
+ Future<void> test_singleFile() async {
+ await resolveTestUnit('''
+f(Iterable<int> i) {
+ var k = 3;
+ return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k);
+}
+
+f2(Iterable<int> i) {
+ return Map.fromIterable(i, key: (k) => k * 2, value: (v) => 0);
+}
+''');
+ await assertHasFix('''
+f(Iterable<int> i) {
+ var k = 3;
+ return { for (var e in i) e * 2 : k };
+}
+
+f2(Iterable<int> i) {
+ return { for (var k in i) k * 2 : 0 };
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 7f0b31c..077f112 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -8,6 +8,8 @@
import 'add_override_test.dart' as add_override;
import 'convert_documentation_into_line_test.dart'
as convert_documentation_into_line;
+import 'convert_map_from_iterable_to_for_literal_test.dart'
+ as convert_map_from_iterable_to_for_literal;
import 'convert_to_contains_test.dart' as convert_to_contains;
import 'convert_to_generic_function_syntax_test.dart'
as convert_to_generic_function_syntax;
@@ -51,6 +53,7 @@
add_await.main();
add_override.main();
convert_documentation_into_line.main();
+ convert_map_from_iterable_to_for_literal.main();
convert_to_contains.main();
convert_to_generic_function_syntax.main();
convert_to_if_element.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index 543f5ac..336979b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix/data_driven/rename.dart';
+import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_error_code.dart';
import 'package:matcher/matcher.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -17,6 +18,26 @@
@reflectiveTest
class TransformSetParserTest extends AbstractTransformSetParserTest {
+ void test_incomplete() {
+ parse('''
+version: 1
+transforms:
+''');
+ expect(result, null);
+ // TODO(brianwilkerson) Report a diagnostic.
+ errorListener.assertErrors([]);
+ }
+
+ void test_invalidYaml() {
+ parse('''
+[
+''');
+ expect(result, null);
+ errorListener.assertErrors([
+ error(TransformSetErrorCode.yamlSyntaxError, 2, 0),
+ ]);
+ }
+
void test_rename() {
parse('''
version: 1
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 1eb1e16..5919677 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -2,6 +2,8 @@
* Added `LocalVariableElement.hasInitializer`,
`PropertyInducingElement.hasInitializer`, `ParameterElement.hasDefaultValue`.
* `ElementImpl.toString()` uses `getDisplayString(withNullability: true)`.
+* Deprecated `ElementAnnotation.constantValue`, it does not guarantee that
+ the value has been computed. Use `computeConstantValue()` instead.
## 0.40.0
* Added `LibraryElement.featureSet`.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 0b17e13..71b8251 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -691,6 +691,7 @@
/// Return a representation of the value of this annotation, or `null` if the
/// value of this annotation has not been computed or if the value could not
/// be computed because of errors.
+ @Deprecated('Use computeConstantValue() instead')
DartObject get constantValue;
/// Return the element representing the field, variable, or const constructor
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9115009..0dfd4db 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2409,6 +2409,7 @@
List<AnalysisError> get constantEvaluationErrors =>
evaluationResult?.errors ?? const <AnalysisError>[];
+ @Deprecated('Use computeConstantValue() instead')
@override
DartObject get constantValue => evaluationResult?.value;
@@ -2565,7 +2566,7 @@
computeConstants(library.typeProvider, library.typeSystem,
context.declaredVariables, [this], analysisOptions.experimentStatus);
}
- return constantValue;
+ return evaluationResult?.value;
}
@override
@@ -7596,6 +7597,7 @@
/// initializers.
Expression get constantInitializer => null;
+ @Deprecated('Use computeConstantValue() instead')
@override
DartObject get constantValue => evaluationResult?.value;
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 9918dee..f27c23b 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -171,12 +171,15 @@
bool isNonNullable(DartType type) {
if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
return false;
+ } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
+ return isNonNullable(type.promotedBound);
} else if (type.nullabilitySuffix == NullabilitySuffix.question) {
return false;
- } else if (type.isDartAsyncFutureOr) {
- return isNonNullable((type as InterfaceType).typeArguments[0]);
+ } else if (type is InterfaceType && type.isDartAsyncFutureOr) {
+ return isNonNullable(type.typeArguments[0]);
} else if (type is TypeParameterType) {
- return isNonNullable(type.bound);
+ var bound = type.element.bound;
+ return bound != null && isNonNullable(bound);
}
return true;
}
@@ -185,6 +188,8 @@
bool isNullable(DartType type) {
if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
return true;
+ } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
+ return isNullable(type.promotedBound);
} else if (type.nullabilitySuffix == NullabilitySuffix.question) {
return true;
} else if (type.isDartAsyncFutureOr) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
index fda77df..cd5deb0 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
@@ -18,7 +18,6 @@
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/task/strong/checker.dart';
import 'package:meta/meta.dart';
/// Helper for resolving [PrefixExpression]s.
@@ -58,6 +57,23 @@
node.operand.accept(_resolver);
+ var operand = node.operand;
+ if (operand is SimpleIdentifier) {
+ var element = operand.staticElement;
+ // ElementResolver does not set it.
+ if (element is VariableElement) {
+ _resolver.setReadElement(operand, element);
+ _resolver.setWriteElement(operand, element);
+ }
+ }
+
+ if (node.readElement == null || node.readType == null) {
+ _resolver.setReadElement(operand, null);
+ }
+ if (node.writeElement == null || node.writeType == null) {
+ _resolver.setWriteElement(operand, null);
+ }
+
if (operator.isIncrementOperator) {
_assignmentShared.checkFinalAlreadyAssigned(node.operand);
}
@@ -67,12 +83,12 @@
}
/// Check that the result [type] of a prefix or postfix `++` or `--`
- /// expression is assignable to the write type of the [operand].
+ /// expression is assignable to the write type of the operand.
///
/// TODO(scheglov) this is duplicate
void _checkForInvalidAssignmentIncDec(
- AstNode node, Expression operand, DartType type) {
- var operandWriteType = _getStaticType(operand);
+ PrefixExpressionImpl node, DartType type) {
+ var operandWriteType = node.writeType;
if (!_typeSystem.isAssignableTo2(type, operandWriteType)) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ASSIGNMENT,
@@ -121,31 +137,6 @@
}
}
- /// Return the static type of the given [expression] that is to be used for
- /// type analysis.
- ///
- /// TODO(scheglov) this is duplicate
- DartType _getStaticType(Expression expression, {bool read = false}) {
- if (read) {
- var type = getReadType(
- expression,
- );
- return _resolveTypeParameter(type);
- } else {
- if (expression is SimpleIdentifier && expression.inSetterContext()) {
- var element = expression.staticElement;
- if (element is PromotableElement) {
- // We're writing to the element so ignore promotions.
- return element.type;
- } else {
- return expression.staticType;
- }
- } else {
- return expression.staticType;
- }
- }
- }
-
/// Return the non-nullable variant of the [type] if NNBD is enabled, otherwise
/// return the type itself.
///
@@ -186,9 +177,9 @@
node.staticElement = member;
return;
}
- DartType staticType = _getStaticType(operand, read: true);
- if (identical(staticType, NeverTypeImpl.instance)) {
+ var readType = node.readType ?? operand.staticType;
+ if (identical(readType, NeverTypeImpl.instance)) {
_resolver.errorReporter.reportErrorForNode(
HintCode.RECEIVER_OF_TYPE_NEVER,
operand,
@@ -198,24 +189,24 @@
var result = _typePropertyResolver.resolve(
receiver: operand,
- receiverType: staticType,
+ receiverType: readType,
name: methodName,
receiverErrorNode: operand,
nameErrorNode: operand,
);
node.staticElement = result.getter;
- if (_shouldReportInvalidMember(staticType, result)) {
+ if (_shouldReportInvalidMember(readType, result)) {
if (operand is SuperExpression) {
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.UNDEFINED_SUPER_OPERATOR,
operator,
- [methodName, staticType],
+ [methodName, readType],
);
} else {
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.UNDEFINED_OPERATOR,
operator,
- [methodName, staticType],
+ [methodName, readType],
);
}
}
@@ -234,11 +225,10 @@
if (operand is ExtensionOverride) {
// No special handling for incremental operators.
} else if (operator.isIncrementOperator) {
- var operandReadType = _getStaticType(operand, read: true);
- if (operandReadType.isDartCoreInt) {
+ if (node.readType.isDartCoreInt) {
staticType = _nonNullable(_typeProvider.intType);
} else {
- _checkForInvalidAssignmentIncDec(node, operand, staticType);
+ _checkForInvalidAssignmentIncDec(node, staticType);
}
if (operand is SimpleIdentifier) {
var element = operand.staticElement;
@@ -266,13 +256,6 @@
_flowAnalysis?.flow?.logicalNot_end(node, operand);
}
- /// If the given [type] is a type parameter, resolve it to the type that should
- /// be used when looking up members. Otherwise, return the original type.
- ///
- /// TODO(scheglov) this is duplicate
- DartType _resolveTypeParameter(DartType type) =>
- type?.resolveToBound(_typeProvider.objectType);
-
/// Return `true` if we should report an error for the lookup [result] on
/// the [type].
///
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 43ab1dd..aef2cc9 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -1480,7 +1480,7 @@
}
for (var annotation in classElement.metadata) {
if (annotation.isTarget) {
- var value = annotation.constantValue;
+ var value = annotation.computeConstantValue();
var kinds = <TargetKind>{};
for (var kindObject in value.getField('kinds').toSetValue()) {
var index = kindObject.getField('index').toIntValue();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 901e787..e2fd8ef 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -596,6 +596,10 @@
parent.operator.type.isIncrementOperator) {
parent.readElement = element;
parent.readType = readType;
+ } else if (parent is PrefixExpressionImpl &&
+ parent.operator.type.isIncrementOperator) {
+ parent.readElement = element;
+ parent.readType = readType;
}
}
@@ -638,6 +642,10 @@
parent.operator.type.isIncrementOperator) {
parent.writeElement = element;
parent.writeType = writeType;
+ } else if (parent is PrefixExpressionImpl &&
+ parent.operator.type.isIncrementOperator) {
+ parent.writeElement = element;
+ parent.writeType = writeType;
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 2522b77..493d29a 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -860,7 +860,7 @@
''');
var result = await driver.getResult(testFile);
Annotation at_x = AstFinder.getClass(result.unit, 'C').metadata[0];
- expect(at_x.elementAnnotation.constantValue.toIntValue(), 1);
+ expect(at_x.elementAnnotation.computeConstantValue().toIntValue(), 1);
}
test_const_circular_reference() async {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 1b926d3..a5956bb 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -858,12 +858,10 @@
ParameterElement parameter = argument.staticParameterElement;
ElementAnnotation annotation = parameter.metadata[0];
- expect(annotation.constantValue, isNull);
DartObject value = annotation.computeConstantValue();
expect(value, isNotNull);
expect(value.getField('f').toStringValue(), 'x');
- expect(annotation.constantValue, value);
}
}
diff --git a/pkg/analyzer/test/src/dart/element/nullable_test.dart b/pkg/analyzer/test/src/dart/element/nullable_test.dart
index 6c98f54..d385bae 100644
--- a/pkg/analyzer/test/src/dart/element/nullable_test.dart
+++ b/pkg/analyzer/test/src/dart/element/nullable_test.dart
@@ -119,7 +119,7 @@
isNotNonNullable(nullStar);
}
- test_typeParameter_noneBound() {
+ test_typeParameter_boundNone() {
var T = typeParameter('T', bound: intNone);
isNonNullable(
@@ -131,7 +131,7 @@
);
}
- test_typeParameter_questionBound() {
+ test_typeParameter_boundQuestion() {
var T = typeParameter('T', bound: intQuestion);
isNotNonNullable(
@@ -143,7 +143,7 @@
);
}
- test_typeParameter_starBound() {
+ test_typeParameter_boundStar() {
var T = typeParameter('T', bound: intStar);
isNonNullable(
@@ -151,6 +151,42 @@
);
}
+ test_typeParameter_promotedBoundNone() {
+ var T = typeParameter('T');
+
+ isNonNullable(
+ typeParameterTypeNone(T, promotedBound: intNone),
+ );
+
+ isNonNullable(
+ typeParameterTypeQuestion(T, promotedBound: intNone),
+ );
+ }
+
+ test_typeParameter_promotedBoundQuestion() {
+ var T = typeParameter('T');
+
+ isNotNonNullable(
+ typeParameterTypeNone(T, promotedBound: intQuestion),
+ );
+
+ isNotNonNullable(
+ typeParameterTypeQuestion(T, promotedBound: intQuestion),
+ );
+ }
+
+ test_typeParameter_promotedBoundStar() {
+ var T = typeParameter('T');
+
+ isNonNullable(
+ typeParameterTypeNone(T, promotedBound: intStar),
+ );
+
+ isNonNullable(
+ typeParameterTypeQuestion(T, promotedBound: intStar),
+ );
+ }
+
test_void() {
isNotNonNullable(voidNone);
}
@@ -248,7 +284,7 @@
isNullable(nullStar);
}
- test_typeParameter_noneBound() {
+ test_typeParameter_boundNone() {
var T = typeParameter('T', bound: intNone);
isNotNullable(
@@ -260,7 +296,7 @@
);
}
- test_typeParameter_questionBound_none() {
+ test_typeParameter_boundQuestion_none() {
var T = typeParameter('T', bound: intQuestion);
isNotNullable(
@@ -272,7 +308,7 @@
);
}
- test_typeParameter_starBound() {
+ test_typeParameter_boundStar() {
var T = typeParameter('T', bound: intStar);
isNotNullable(
@@ -280,6 +316,42 @@
);
}
+ test_typeParameter_promotedBoundNone() {
+ var T = typeParameter('T');
+
+ isNotNullable(
+ typeParameterTypeNone(T, promotedBound: intNone),
+ );
+
+ isNotNullable(
+ typeParameterTypeQuestion(T, promotedBound: intNone),
+ );
+ }
+
+ test_typeParameter_promotedBoundQuestion() {
+ var T = typeParameter('T');
+
+ isNullable(
+ typeParameterTypeNone(T, promotedBound: intQuestion),
+ );
+
+ isNullable(
+ typeParameterTypeQuestion(T, promotedBound: intQuestion),
+ );
+ }
+
+ test_typeParameter_promotedBoundStar() {
+ var T = typeParameter('T');
+
+ isNotNullable(
+ typeParameterTypeNone(T, promotedBound: intStar),
+ );
+
+ isNotNullable(
+ typeParameterTypeQuestion(T, promotedBound: intStar),
+ );
+ }
+
test_void() {
isNullable(voidNone);
}
@@ -473,7 +545,7 @@
isNotStrictlyNonNullable(nullStar);
}
- test_typeParameter_noneBound() {
+ test_typeParameter_boundNone() {
var T = typeParameter('T', bound: intNone);
isStrictlyNonNullable(
@@ -489,7 +561,7 @@
);
}
- test_typeParameter_questionBound() {
+ test_typeParameter_boundQuestion() {
var T = typeParameter('T', bound: intQuestion);
isNotStrictlyNonNullable(
@@ -505,7 +577,7 @@
);
}
- test_typeParameter_starBound() {
+ test_typeParameter_boundStar() {
var T = typeParameter('T', bound: intStar);
isNotStrictlyNonNullable(
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 11c9ec8..0d0a042 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -40,7 +40,7 @@
// To evaluate `const A()` we have to evaluate `{int p}`.
// Even if its value is `null`.
expect(p.isConstantEvaluated, isTrue);
- expect(p.constantValue.isNull, isTrue);
+ expect(p.computeConstantValue().isNull, isTrue);
}
test_constFactoryRedirection_super() async {
@@ -64,7 +64,7 @@
''');
var node = findNode.annotation('@I');
- var value = node.elementAnnotation.constantValue;
+ var value = node.elementAnnotation.computeConstantValue();
expect(value.getField('(super)').getField('f').toIntValue(), 42);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index 1d159f9..14ddc4ca 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -38,6 +39,10 @@
assertPrefixExpression(
findNode.prefix('!f()'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: boolElement.getMethod('!'),
type: 'bool',
);
@@ -45,13 +50,17 @@
test_bang_bool_localVariable() async {
await assertNoErrorsInCode(r'''
-f(bool x) {
+void f(bool x) {
!x;
}
''');
assertPrefixExpression(
findNode.prefix('!x'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: boolElement.getMethod('!'),
type: 'bool',
);
@@ -59,29 +68,117 @@
test_bang_int_localVariable() async {
await assertErrorsInCode(r'''
-f(int x) {
+void f(int x) {
!x;
}
''', [
- error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 14, 1),
+ error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 19, 1),
]);
assertPrefixExpression(
findNode.prefix('!x'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: null,
type: 'bool',
);
}
- test_minus_int_localVariable() async {
+ test_inc_indexExpression_instance() async {
await assertNoErrorsInCode(r'''
-f(int x) {
+class A {
+ int operator[](int index) => 0;
+ operator[]=(int index, num _) {}
+}
+
+void f(A a) {
+ ++a[0];
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++'),
+ readElement: findElement.method('[]'),
+ readType: 'int',
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_inc_indexExpression_super() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int operator[](int index) => 0;
+ operator[]=(int index, num _) {}
+}
+
+class B extends A {
+ void f(A a) {
+ ++super[0];
+ }
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++'),
+ readElement: findElement.method('[]'),
+ readType: 'int',
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_inc_indexExpression_this() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int operator[](int index) => 0;
+ operator[]=(int index, num _) {}
+
+ void f() {
+ ++this[0];
+ }
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++'),
+ readElement: findElement.method('[]'),
+ readType: 'int',
+ writeElement: findElement.method('[]='),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_minus_simpleIdentifier_parameter_int() async {
+ await assertNoErrorsInCode(r'''
+void f(int x) {
-x;
}
''');
assertPrefixExpression(
findNode.prefix('-x'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: elementMatcher(
intElement.getMethod('unary-'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
@@ -90,24 +187,7 @@
);
}
- test_plusPlus_double() async {
- await assertNoErrorsInCode(r'''
-f(double x) {
- ++x;
-}
-''');
-
- assertPrefixExpression(
- findNode.prefix('++x'),
- element: elementMatcher(
- doubleElement.getMethod('+'),
- isLegacy: isNullSafetySdkAndLegacyLibrary,
- ),
- type: 'double',
- );
- }
-
- test_plusPlus_extensionOverride() async {
+ test_plusPlus_notLValue_extensionOverride() async {
await assertErrorsInCode(r'''
class C {}
@@ -117,29 +197,41 @@
}
}
-f(C c) {
+void f(C c) {
++Ext(c);
}
''', [
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 98, 1),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 103, 1),
]);
assertPrefixExpression(
findNode.prefix('++Ext'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: null,
+ writeType: 'dynamic',
element: findElement.method('+'),
type: 'int',
);
}
- test_plusPlus_int_localVariable() async {
+ test_plusPlus_prefixedIdentifier_instance() async {
await assertNoErrorsInCode(r'''
-f(int x) {
- ++x;
+class A {
+ int x = 0;
+}
+
+void f(A a) {
+ ++a.x;
}
''');
assertPrefixExpression(
- findNode.prefix('++x'),
+ findNode.prefix('++'),
+ readElement: findElement.getter('x'),
+ readType: 'int',
+ writeElement: findElement.setter('x'),
+ writeType: 'int',
element: elementMatcher(
numElement.getMethod('+'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
@@ -148,19 +240,55 @@
);
}
- /// Verify that we get all necessary types when building the dependencies
- /// graph during top-level inference.
- test_plusPlus_int_topLevelInference() async {
+ test_plusPlus_prefixedIdentifier_topLevel() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+int x = 0;
+''');
await assertNoErrorsInCode(r'''
-var x = 0;
+import 'a.dart' as p;
-class M1 {
- final y = ++x;
+void f() {
+ ++p.x;
+}
+''');
+
+ var importFind = findElement.importFind('package:test/a.dart');
+
+ var prefix = findNode.prefix('++');
+ assertPrefixExpression(
+ prefix,
+ readElement: importFind.topGet('x'),
+ readType: 'int',
+ writeElement: importFind.topSet('x'),
+ writeType: 'int',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+
+ var prefixed = prefix.operand as PrefixedIdentifier;
+ assertImportPrefix(prefixed.prefix, importFind.prefix);
+ }
+
+ test_plusPlus_propertyAccess_instance() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int x = 0;
+}
+
+void f() {
+ ++A().x;
}
''');
assertPrefixExpression(
- findNode.prefix('++x'),
+ findNode.prefix('++'),
+ readElement: findElement.getter('x'),
+ readType: 'int',
+ writeElement: findElement.setter('x'),
+ writeType: 'int',
element: elementMatcher(
numElement.getMethod('+'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
@@ -169,15 +297,118 @@
);
}
- test_plusPlus_num() async {
+ test_plusPlus_propertyAccess_super() async {
await assertNoErrorsInCode(r'''
-f(num x) {
+class A {
+ set x(num _) {}
+ int get x => 0;
+}
+
+class B extends A {
+ set x(num _) {}
+ int get x => 0;
+
+ void f() {
+ ++super.x;
+ }
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++'),
+ readElement: findElement.getter('x', of: 'A'),
+ readType: 'int',
+ writeElement: findElement.setter('x', of: 'A'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_plusPlus_propertyAccess_this() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ set x(num _) {}
+ int get x => 0;
+
+ void f() {
+ ++this.x;
+ }
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++'),
+ readElement: findElement.getter('x'),
+ readType: 'int',
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_parameter_double() async {
+ await assertNoErrorsInCode(r'''
+void f(double x) {
++x;
}
''');
assertPrefixExpression(
findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'double',
+ writeElement: findElement.parameter('x'),
+ writeType: 'double',
+ element: elementMatcher(
+ doubleElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'double',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_parameter_int() async {
+ await assertNoErrorsInCode(r'''
+void f(int x) {
+ ++x;
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'int',
+ writeElement: findElement.parameter('x'),
+ writeType: 'int',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_parameter_num() async {
+ await assertNoErrorsInCode(r'''
+void f(num x) {
+ ++x;
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'num',
+ writeElement: findElement.parameter('x'),
+ writeType: 'num',
element: elementMatcher(
numElement.getMethod('+'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
@@ -186,15 +417,227 @@
);
}
- test_tilde_int_localVariable() async {
+ test_plusPlus_simpleIdentifier_parameter_typeParameter() async {
+ await assertErrorsInCode(
+ r'''
+void f<T extends num>(T x) {
+ ++x;
+}
+''',
+ expectedErrorsByNullability(nullable: [
+ error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 31, 3),
+ ], legacy: []),
+ );
+
+ assertPrefixExpression(
+ findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'T',
+ writeElement: findElement.parameter('x'),
+ writeType: 'T',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'num',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_thisGetter_superSetter() async {
await assertNoErrorsInCode(r'''
-f(int x) {
+class A {
+ set x(num _) {}
+}
+
+class B extends A {
+ int get x => 0;
+ void f() {
+ ++x;
+ }
+}
+''');
+
+ var prefix = findNode.prefix('++x');
+ assertPrefixExpression(
+ prefix,
+ readElement: findElement.getter('x'),
+ readType: 'int',
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ prefix.operand,
+ readElement: findElement.getter('x'),
+ writeElement: findElement.setter('x'),
+ type: 'num',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_thisGetter_thisSetter() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ int get x => 0;
+ set x(num _) {}
+ void f() {
+ ++x;
+ }
+}
+''');
+
+ var prefix = findNode.prefix('++x');
+ assertPrefixExpression(
+ prefix,
+ readElement: findElement.getter('x'),
+ readType: 'int',
+ writeElement: findElement.setter('x'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ prefix.operand,
+ readElement: findElement.getter('x'),
+ writeElement: findElement.setter('x'),
+ type: 'num',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_topGetter_topSetter() async {
+ await assertNoErrorsInCode(r'''
+int get x => 0;
+
+set x(num _) {}
+
+void f() {
+ ++x;
+}
+''');
+
+ var prefix = findNode.prefix('++x');
+ assertPrefixExpression(
+ prefix,
+ readElement: findElement.topGet('x'),
+ readType: 'int',
+ writeElement: findElement.topSet('x'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ prefix.operand,
+ readElement: findElement.topGet('x'),
+ writeElement: findElement.topSet('x'),
+ type: 'num',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_topGetter_topSetter_fromClass() async {
+ await assertNoErrorsInCode(r'''
+int get x => 0;
+
+set x(num _) {}
+
+class A {
+ void f() {
+ ++x;
+ }
+}
+''');
+
+ var prefix = findNode.prefix('++x');
+ assertPrefixExpression(
+ prefix,
+ readElement: findElement.topGet('x'),
+ readType: 'int',
+ writeElement: findElement.topSet('x'),
+ writeType: 'num',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+
+ assertSimpleIdentifier(
+ prefix.operand,
+ readElement: findElement.topGet('x'),
+ writeElement: findElement.topSet('x'),
+ type: 'num',
+ );
+ }
+
+ test_plusPlus_simpleIdentifier_typeLiteral() async {
+ await assertErrorsInCode(r'''
+void f() {
+ ++int;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, 15, 3),
+ ]);
+
+ assertPrefixExpression(
+ findNode.prefix('++int'),
+ readElement: null,
+ readType: 'dynamic',
+ writeElement: intElement,
+ writeType: 'dynamic',
+ element: null,
+ type: 'dynamic',
+ );
+ }
+
+ /// Verify that we get all necessary types when building the dependencies
+ /// graph during top-level inference.
+ test_plusPlus_topLevelInference() async {
+ await assertNoErrorsInCode(r'''
+var x = 0;
+
+class A {
+ final y = ++x;
+}
+''');
+
+ assertPrefixExpression(
+ findNode.prefix('++x'),
+ readElement: findElement.topGet('x'),
+ readType: 'int',
+ writeElement: findElement.topSet('x'),
+ writeType: 'int',
+ element: elementMatcher(
+ numElement.getMethod('+'),
+ isLegacy: isNullSafetySdkAndLegacyLibrary,
+ ),
+ type: 'int',
+ );
+ }
+
+ test_tilde_simpleIdentifier_parameter_int() async {
+ await assertNoErrorsInCode(r'''
+void f(int x) {
~x;
}
''');
assertPrefixExpression(
findNode.prefix('~x'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: elementMatcher(
intElement.getMethod('~'),
isLegacy: isNullSafetySdkAndLegacyLibrary,
@@ -222,6 +665,10 @@
assertPrefixExpression(
findNode.prefix('!a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: boolElement.getMethod('!'),
type: 'bool',
);
@@ -242,6 +689,10 @@
assertPrefixExpression(
findNode.prefix('-a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: intElement.getMethod('unary-'),
type: 'int',
);
@@ -253,7 +704,7 @@
Object operator +(int _) => this;
}
-f(Object x) {
+void f(Object x) {
if (x is A) {
++x;
}
@@ -262,6 +713,10 @@
assertPrefixExpression(
findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'A',
+ writeElement: findElement.parameter('x'),
+ writeType: 'Object',
element: findElement.method('+'),
type: 'Object',
);
@@ -275,13 +730,17 @@
int foo = 0;
}
-f(A? a) {
+void f(A? a) {
++a?.foo;
}
''');
assertPrefixExpression(
findNode.prefix('++a'),
+ readElement: findElement.getter('foo'),
+ readType: 'int',
+ writeElement: findElement.setter('foo'),
+ writeType: 'int',
element: numElement.getMethod('+'),
type: 'int?',
);
@@ -302,6 +761,10 @@
assertPrefixExpression(
findNode.prefix('~a'),
+ readElement: null,
+ readType: null,
+ writeElement: null,
+ writeType: null,
element: intElement.getMethod('~'),
type: 'int',
);
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 9d4bf8d..be1327b 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -615,9 +615,20 @@
void assertPrefixExpression(
PrefixExpression node, {
+ @required Object readElement,
+ @required String readType,
+ @required Object writeElement,
+ @required String writeType,
@required Object element,
@required String type,
}) {
+ assertCompoundAssignment(
+ node,
+ readElement: readElement,
+ readType: readType,
+ writeElement: writeElement,
+ writeType: writeType,
+ );
assertElement(node.staticElement, element);
assertType(node, type);
}
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index 01bb301..a5edc42 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -364,6 +364,10 @@
assertPrefixExpression(
findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'Never',
+ writeElement: findElement.parameter('x'),
+ writeType: 'Never',
element: null,
type: 'Never',
);
@@ -380,6 +384,10 @@
assertPrefixExpression(
findNode.prefix('++x'),
+ readElement: findElement.parameter('x'),
+ readType: 'Never?',
+ writeElement: findElement.parameter('x'),
+ writeType: 'Never?',
element: null,
type: 'dynamic',
);
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart b/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
index 21b6a29..f91a311 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powerset_bits.dart
@@ -35,15 +35,26 @@
static const int _nullIndex = 2;
static const int _otherIndex = 3;
- static const int _maxIndex = _otherIndex;
+ static const int _interceptorIndex = 4;
+ static const int _notInterceptorIndex = 5;
+ static const int _nullInterceptorIndex = 6;
+ static const int _maxIndex = _nullInterceptorIndex;
static const List<int> _singletonIndices = [
_trueIndex,
_falseIndex,
_nullIndex,
];
- static const List<String> _bitNames = ['true', 'false', 'null', 'other'];
+ static const List<String> _bitNames = [
+ 'true',
+ 'false',
+ 'null',
+ 'other',
+ 'interceptor',
+ 'notInterceptor',
+ 'null'
+ ];
PowersetBitsDomain(this._closedWorld);
@@ -62,16 +73,35 @@
int get preciseMask => _singletonIndices.fold(
powersetBottom, (mask, index) => mask | 1 << index);
+ int get interceptorMask => 1 << _interceptorIndex;
+ int get notInterceptorMask => 1 << _notInterceptorIndex;
+ int get nullInterceptorMask => 1 << _nullInterceptorIndex;
+ int get interceptorDomainMask =>
+ interceptorMask | notInterceptorMask | nullInterceptorMask;
+
int get powersetBottom => 0;
int get powersetTop => (1 << _maxIndex + 1) - 1;
+ int get trueValue => trueMask | interceptorMask;
+ int get falseValue => falseMask | interceptorMask;
+ int get boolValue => boolMask | interceptorMask;
+ int get nullValue => nullMask | nullInterceptorMask;
+ int get otherValue => otherMask | interceptorMask | notInterceptorMask;
+ int get interceptorOtherValue => otherMask | interceptorMask;
+
bool isPotentiallyBoolean(int value) => (value & boolMask) != 0;
bool isPotentiallyNull(int value) => (value & nullMask) != 0;
bool isPotentiallyOther(int value) => (value & otherMask) != 0;
+ bool isPotentiallyInterceptor(int value) => (value & interceptorMask) != 0;
+ bool isPotentiallyNotInterceptor(int value) =>
+ (value & notInterceptorMask) != 0;
+ bool isPotentiallyNullInterceptor(int value) =>
+ (value & notInterceptorMask) != 0;
- bool isDefinitelyTrue(int value) => value == trueMask;
- bool isDefinitelyFalse(int value) => value == falseMask;
- bool isDefinitelyNull(int value) => value == nullMask;
+ bool isDefinitelyTrue(int value) => value == trueValue;
+ bool isDefinitelyFalse(int value) => value == falseValue;
+ bool isDefinitelyNull(int value) => value == nullValue;
+
bool isSingleton(int value) =>
isDefinitelyTrue(value) ||
isDefinitelyFalse(value) ||
@@ -83,19 +113,13 @@
AbstractBool isOther(int value) =>
AbstractBool.maybeOrFalse(isPotentiallyOther(value));
- AbstractBool isIn(int subset, int superset) {
- if (union(subset, superset) == superset) {
- if (isPrecise(superset)) return AbstractBool.True;
- } else {
- if (isPrecise(subset)) return AbstractBool.False;
- }
- return AbstractBool.Maybe;
- }
-
/// Returns a descriptive string for [bits]
static String toText(int bits, {bool omitIfTop = false}) {
- int boolDomainMask = (1 << _maxIndex + 1) - 1;
- return _toTextDomain(bits, boolDomainMask, omitIfTop);
+ int boolNullOtherMask = (1 << _otherIndex + 1) - 1;
+ int interceptorDomainMask =
+ (1 << _nullInterceptorIndex + 1) - (1 << _interceptorIndex);
+ return _toTextDomain(bits, interceptorDomainMask, omitIfTop) +
+ _toTextDomain(bits, boolNullOtherMask, omitIfTop);
}
/// Returns a descriptive string for a subset of [bits] defined by
@@ -119,6 +143,20 @@
return '$sb';
}
+ AbstractBool _isIn(int subset, int superset) {
+ if (union(subset, superset) == superset) {
+ if (isPrecise(superset)) return AbstractBool.True;
+ } else {
+ if (isPrecise(subset)) return AbstractBool.False;
+ }
+ return AbstractBool.Maybe;
+ }
+
+ AbstractBool isIn(int subset, int superset) {
+ // TODO(coam): We can also take advantage of other bits to be more precise
+ return _isIn(subset & boolNullOtherMask, superset & boolNullOtherMask);
+ }
+
AbstractBool needsNoSuchMethodHandling(int receiver, Selector selector) =>
AbstractBool.Maybe;
@@ -154,20 +192,26 @@
int computeAbstractValueForConstant(ConstantValue value) {
if (value.isTrue) {
- return trueMask;
+ return trueValue;
}
if (value.isFalse) {
- return falseMask;
+ return falseValue;
}
if (value.isNull) {
- return nullMask;
+ return nullValue;
}
- return otherMask;
+
+ // TODO(coam): We could be more precise if we implement a visitor to
+ // ConstantValue
+ return createFromStaticType(value.getType(commonElements), nullable: false);
}
AbstractBool areDisjoint(int a, int b) {
int overlap = intersection(a, b);
- if (overlap == powersetBottom) return AbstractBool.True;
+ if (overlap & interceptorDomainMask == powersetBottom) {
+ return AbstractBool.True;
+ }
+ if (overlap & boolNullOtherMask == powersetBottom) return AbstractBool.True;
if (isPrecise(overlap)) return AbstractBool.False;
return AbstractBool.Maybe;
}
@@ -221,7 +265,11 @@
AbstractBool isInteger(int value) => isOther(value);
- AbstractBool isInterceptor(int value) => AbstractBool.Maybe;
+ AbstractBool isInterceptor(int value) {
+ if (!isPotentiallyInterceptor(value)) return AbstractBool.False;
+ if (isPotentiallyNotInterceptor(value)) return AbstractBool.Maybe;
+ return AbstractBool.True;
+ }
AbstractBool isPrimitiveString(int value) => isOther(value);
@@ -261,7 +309,9 @@
AbstractBool isExact(int value) => AbstractBool.Maybe;
AbstractBool isEmpty(int value) {
- if (value == powersetBottom) return AbstractBool.True;
+ if (value & interceptorDomainMask == powersetBottom)
+ return AbstractBool.True;
+ if (value & boolNullOtherMask == powersetBottom) return AbstractBool.True;
if (isPrecise(value)) return AbstractBool.False;
return AbstractBool.Maybe;
}
@@ -280,11 +330,11 @@
AbstractBool containsType(int value, ClassEntity cls) => AbstractBool.Maybe;
int includeNull(int value) {
- return value | nullMask;
+ return value | nullValue;
}
int excludeNull(int value) {
- return value & ~nullMask;
+ return value & ~nullValue;
}
AbstractBool couldBeTypedArray(int value) => isOther(value);
@@ -299,39 +349,43 @@
return cls == commonElements.jsNullClass || cls == commonElements.nullClass;
}
- // This function checks if cls is one of those classes other than bool or null
- // that are live by default in a program.
- bool _isLiveByDefault(ClassEntity cls) {
- return cls == commonElements.intClass ||
- cls == commonElements.numClass ||
- cls == commonElements.doubleClass ||
- cls == commonElements.stringClass;
- }
-
ClassInfo _computeClassInfo(ClassEntity cls) {
ClassInfo classInfo = _storedClassInfo[cls];
if (classInfo != null) {
return classInfo;
}
- // Bool and Null are handled specially because the powerset bits
- // contain information about values being bool or null.
+ // Handle null case specially
if (_isNullSubtype(cls)) {
- classInfo = ClassInfo(nullMask, powersetBottom, powersetBottom);
- _storedClassInfo[cls] = classInfo;
- return classInfo;
- }
- if (_isBoolSubtype(cls)) {
- classInfo = ClassInfo(boolMask, powersetBottom, powersetBottom);
+ classInfo = ClassInfo(nullValue, powersetBottom, powersetBottom);
_storedClassInfo[cls] = classInfo;
return classInfo;
}
- // If cls is instantiated or live by default the 'other' bit should be set to 1.
- int exactBits = powersetBottom;
- if (_isLiveByDefault(cls) ||
- _closedWorld.classHierarchy.isInstantiated(cls)) {
- exactBits = otherMask;
+ // Handle bool and JSBool specially. Both appear to be 'instantiated' but
+ // only JSBool is really instantiated.
+ if (_isBoolSubtype(cls)) {
+ int exactBits = boolMask | interceptorMask;
+ classInfo = ClassInfo(exactBits, powersetBottom, powersetBottom);
+ _storedClassInfo[cls] = classInfo;
+ return classInfo;
+ }
+
+ // Compute interceptor and notInterceptor bits first
+ int interceptorBits = powersetBottom;
+ if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+ if (_closedWorld.classHierarchy
+ .isSubclassOf(cls, commonElements.jsInterceptorClass)) {
+ interceptorBits |= interceptorMask;
+ } else {
+ interceptorBits |= notInterceptorMask;
+ }
+ }
+
+ int exactBits = interceptorBits;
+ if (_closedWorld.classHierarchy.isInstantiated(cls)) {
+ // If cls is instantiated or live by default the 'other' bit should be set to 1.
+ exactBits |= otherMask;
}
int strictSubtypeBits = powersetBottom;
@@ -517,43 +571,65 @@
int get emptyType => powersetBottom;
- int get constMapType => otherMask;
+ int _constMapType;
+ int get constMapType => _constMapType ??=
+ createNonNullSubtype(commonElements.constMapLiteralClass);
- int get constSetType => otherMask;
+ int get constSetType => otherValue;
- int get constListType => otherMask;
+ int _constListType;
+ int get constListType => _constListType ??=
+ createNonNullExact(commonElements.jsUnmodifiableArrayClass);
- int get positiveIntType => otherMask;
+ int _fixedListType;
+ int get fixedListType =>
+ _fixedListType ??= createNonNullExact(commonElements.jsFixedArrayClass);
- int get uint32Type => otherMask;
+ int _growableListType;
+ int get growableListType => _growableListType ??=
+ createNonNullExact(commonElements.jsExtendableArrayClass);
- int get uint31Type => otherMask;
+ int get nullType => nullValue;
- int get fixedListType => otherMask;
+ int get nonNullType => powersetTop & ~nullValue;
- int get growableListType => otherMask;
+ int _mapType;
+ int get mapType =>
+ _mapType ??= createNonNullSubtype(commonElements.mapLiteralClass);
- int get nullType => nullMask;
+ int _setType;
+ int get setType =>
+ _setType ??= createNonNullSubtype(commonElements.setLiteralClass);
- int get nonNullType => otherMask;
+ int _listType;
+ int get listType =>
+ _listType ??= createNonNullExact(commonElements.jsArrayClass);
- int get mapType => otherMask;
+ int _stringType;
+ int get stringType =>
+ _stringType ??= createNonNullSubtype(commonElements.jsStringClass);
- int get setType => otherMask;
+ int _numType;
+ int get numType =>
+ _numType ??= createNonNullSubclass(commonElements.jsNumberClass);
- int get listType => otherMask;
+ int _doubleType;
+ int get doubleType =>
+ _doubleType ??= createNonNullExact(commonElements.jsDoubleClass);
- int get stringType => otherMask;
+ int _intType;
+ int get intType =>
+ _intType ??= createNonNullSubtype(commonElements.jsIntClass);
- int get numType => otherMask;
+ int get positiveIntType => intType;
+ int get uint32Type => intType;
+ int get uint31Type => intType;
- int get doubleType => otherMask;
+ int get boolType => boolValue;
- int get intType => otherMask;
+ int _functionType;
+ int get functionType =>
+ _functionType ??= createNonNullSubtype(commonElements.functionClass);
- int get boolType => boolMask;
-
- int get functionType => otherMask;
-
- int get typeType => otherMask;
+ int get typeType => otherValue;
}
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
index 0d5fb61..61a5124 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
@@ -18,7 +18,7 @@
class PowersetValue implements AbstractValue {
final AbstractValue _abstractValue;
final int _powersetBits;
- const PowersetValue(this._abstractValue, this._powersetBits);
+ PowersetValue(this._abstractValue, this._powersetBits);
AbstractValue get abstractValue => _abstractValue;
int get powersetBits => _powersetBits;
@@ -143,7 +143,7 @@
@override
AbstractValue computeReceiver(Iterable<MemberEntity> members) {
- int powersetBits = _powersetBitsDomain.powersetTop;
+ int powersetBits = _powersetBitsDomain.computeReceiver(members);
AbstractValue abstractValue = _abstractValueDomain.computeReceiver(members);
return PowersetValue(abstractValue, powersetBits);
}
@@ -213,7 +213,7 @@
covariant PowersetValue key,
covariant PowersetValue value,
covariant Map<String, AbstractValue> mappings) {
- int powersetBits = _powersetBitsDomain.otherMask;
+ int powersetBits = originalValue._powersetBits;
AbstractValue abstractValue = _abstractValueDomain.createDictionaryValue(
originalValue._abstractValue,
allocationNode,
@@ -258,7 +258,7 @@
MemberEntity allocationElement,
covariant PowersetValue key,
covariant PowersetValue value) {
- int powersetBits = _powersetBitsDomain.otherMask;
+ int powersetBits = originalValue._powersetBits;
AbstractValue abstractValue = _abstractValueDomain.createMapValue(
originalValue._abstractValue,
allocationNode,
@@ -289,7 +289,7 @@
Object allocationNode,
MemberEntity allocationElement,
covariant PowersetValue elementType) {
- int powersetBits = _powersetBitsDomain.otherMask;
+ int powersetBits = originalValue._powersetBits;
AbstractValue abstractValue = _abstractValueDomain.createSetValue(
originalValue._abstractValue,
allocationNode,
@@ -326,7 +326,7 @@
MemberEntity allocationElement,
covariant PowersetValue elementType,
int length) {
- int powersetBits = _powersetBitsDomain.otherMask;
+ int powersetBits = originalValue._powersetBits;
AbstractValue abstractValue = _abstractValueDomain.createContainerValue(
originalValue._abstractValue,
allocationNode,
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index a484821..f03685c 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -92,10 +92,6 @@
bool canUseSelfForInterceptor(HInstruction receiver,
{Set<ClassEntity> interceptedClasses}) {
- if (receiver.isPrimitive(_abstractValueDomain).isPotentiallyTrue) {
- // Primitives always need interceptors.
- return false;
- }
if (receiver.isNull(_abstractValueDomain).isPotentiallyTrue) {
if (interceptedClasses == null ||
interceptedClasses.contains(_commonElements.jsNullClass)) {
diff --git a/pkg/compiler/test/inference/powerset_bits2_test.dart b/pkg/compiler/test/inference/powerset_bits2_test.dart
index 3ed02cd..db5fe3d 100644
--- a/pkg/compiler/test/inference/powerset_bits2_test.dart
+++ b/pkg/compiler/test/inference/powerset_bits2_test.dart
@@ -39,8 +39,8 @@
PowersetDomain powersetDomain = closedWorld.abstractValueDomain;
PowersetBitsDomain powersetBitsDomain = powersetDomain.powersetBitsDomain;
- var exactTrue = powersetBitsDomain.trueMask;
- var exactFalse = powersetBitsDomain.falseMask;
+ var exactTrue = powersetBitsDomain.trueValue;
+ var exactFalse = powersetBitsDomain.falseValue;
dynamic classA =
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'A');
var exactA = powersetBitsDomain.createNonNullExact(classA);
diff --git a/pkg/compiler/test/inference/powerset_bits3_test.dart b/pkg/compiler/test/inference/powerset_bits3_test.dart
new file mode 100644
index 0000000..1f275a9
--- /dev/null
+++ b/pkg/compiler/test/inference/powerset_bits3_test.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.
+
+// @dart = 2.7
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/inferrer/abstract_value_domain.dart';
+import 'package:compiler/src/inferrer/powersets/powersets.dart';
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import '../helpers/element_lookup.dart';
+import '../helpers/memory_compiler.dart';
+
+const String CODE = """
+class A extends Comparable {
+ int compareTo(x) { return 0; }
+}
+class B extends Comparable {
+ int compareTo(x) { return 0; }
+}
+class C extends Comparable {
+ int compareTo(x) { return 0; }
+}
+class D extends Comparable {
+ int compareTo(x) { return 0; }
+}
+class E extends Comparable {
+ int compareTo(x) { return 0; }
+}
+
+var sink;
+test(x) {
+ if (x.compareTo(x)) {
+ sink = x;
+ }
+}
+
+var sink2;
+test2(x) {
+ sink2 = x;
+ print(x);
+}
+
+var sink3;
+test3(x) {
+ sink3 = x;
+ print(x);
+}
+
+
+main() {
+ A a = A();
+ B b = B();
+ C c = C();
+ D d = D();
+ E e = E();
+ test(a);
+ test(b);
+ test(c);
+ test(d);
+ test(e);
+ test2(-1);
+ test2(1);
+ test2("x");
+ test3([1]);
+ test3(0);
+ test3(a);
+}
+""";
+
+main() {
+ retainDataForTesting = true;
+
+ runTests() async {
+ CompilationResult result = await runCompiler(memorySourceFiles: {
+ 'main.dart': CODE
+ }, options: [
+ '--experimental-powersets',
+ ]);
+ Expect.isTrue(result.isSuccess);
+ Compiler compiler = result.compiler;
+ var results = compiler.globalInference.resultsForTesting;
+ JClosedWorld closedWorld = results.closedWorld;
+ PowersetDomain powersetDomain = closedWorld.abstractValueDomain;
+
+ checkInterceptor(String name, {AbstractBool result = AbstractBool.True}) {
+ var element = findMember(closedWorld, name);
+ PowersetValue value = results.resultOfMember(element).type;
+ Expect.equals(powersetDomain.isInterceptor(value), result);
+ }
+
+ checkInterceptor('sink', result: AbstractBool.False);
+ checkInterceptor('sink2');
+ checkInterceptor('sink3', result: AbstractBool.Maybe);
+ }
+
+ asyncTest(() async {
+ print('--test from kernel------------------------------------------------');
+ await runTests();
+ });
+}
diff --git a/pkg/compiler/test/inference/powerset_bits_test.dart b/pkg/compiler/test/inference/powerset_bits_test.dart
index 4261af7..0bf0a6e 100644
--- a/pkg/compiler/test/inference/powerset_bits_test.dart
+++ b/pkg/compiler/test/inference/powerset_bits_test.dart
@@ -56,11 +56,12 @@
Expect.equals(bits, mask.powersetBits);
}
- checkBits('a', powersetBitsDomain.trueMask);
- checkBits('b', powersetBitsDomain.boolMask);
- checkBits('c', powersetBitsDomain.boolMask);
- checkBits('d', powersetBitsDomain.boolMask);
- checkBits('e', powersetBitsDomain.falseMask | powersetBitsDomain.nullMask);
+ checkBits('a', powersetBitsDomain.trueValue);
+ checkBits('b', powersetBitsDomain.boolValue);
+ checkBits('c', powersetBitsDomain.boolValue);
+ checkBits('d', powersetBitsDomain.boolValue);
+ checkBits(
+ 'e', powersetBitsDomain.falseValue | powersetBitsDomain.nullValue);
}
asyncTest(() async {
diff --git a/pkg/dartdev/README.md b/pkg/dartdev/README.md
index f2662cc..25e92b1 100644
--- a/pkg/dartdev/README.md
+++ b/pkg/dartdev/README.md
@@ -7,18 +7,18 @@
Global options:
-h, --help Print this usage information.
--v, --verbose Show verbose output.
+-v, --verbose Show additional command output.
--version Print the Dart SDK version.
--enable-analytics Enable anonymous analytics.
--disable-analytics Disable anonymous analytics.
Available commands:
analyze Analyze the project's Dart code.
+ compile Compile Dart to various formats.
create Create a new project.
- format Format Dart source code.
- migrate Perform a null safety migration on a project or package.
+ format Idiomatically formats Dart source code.
pub Work with packages.
- run Run a Dart file.
+ run Run a Dart program.
test Runs tests in this project.
Run "dart help <command>" for more information about a command.
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 275c8c2..72df662 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -247,9 +247,9 @@
argParser.addMultiOption(
experimentFlagName,
valueHelp: 'experiment',
- allowed: features.map((feature) => feature.enableString),
allowedHelp: verbose ? allowedHelp : null,
- help: 'Enable one or more experimental features.',
+ help: 'Enable one or more experimental features '
+ '(see dart.dev/go/experiments).',
);
}
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index e78e881..139d262 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -12,9 +12,14 @@
import '../utils.dart';
import 'analyze_impl.dart';
-// TODO: Support enable-experiment for 'dart analyze'.
-
class AnalyzeCommand extends DartdevCommand<int> {
+ /// The maximum length of any of the existing severity labels.
+ static const int _severityWidth = 7;
+
+ /// The number of spaces needed to indent follow-on lines (the body) under the
+ /// message. The width left for the severity label plus the separator width.
+ static const int _bodyIndentWidth = _severityWidth + 3;
+
AnalyzeCommand() : super('analyze', "Analyze the project's Dart code.") {
argParser
..addFlag('fatal-infos',
@@ -91,7 +96,7 @@
// error • Message ... at path.dart:line:col • (code)
var filePath = path.relative(error.file, from: dir.path);
- var severity = error.severity.toLowerCase().padLeft(7);
+ var severity = error.severity.toLowerCase().padLeft(_severityWidth);
if (error.isError) {
severity = log.ansi.error(severity);
}
@@ -104,7 +109,7 @@
);
if (verbose) {
- var padding = ' '.padLeft(error.severity.length + 2);
+ var padding = ' ' * _bodyIndentWidth;
for (var message in error.contextMessages) {
log.stdout('$padding${message.message} '
'at ${message.filePath}:${message.line}:${message.column}');
diff --git a/pkg/dartdev/lib/src/commands/analyze_impl.dart b/pkg/dartdev/lib/src/commands/analyze_impl.dart
index e3e7396..714753d 100644
--- a/pkg/dartdev/lib/src/commands/analyze_impl.dart
+++ b/pkg/dartdev/lib/src/commands/analyze_impl.dart
@@ -239,6 +239,10 @@
List<DiagnosticMessage> get contextMessages {
var messages = json['contextMessages'] as List<dynamic>;
+ if (messages == null) {
+ // The field is optional, so we return an empty list as a default value.
+ return [];
+ }
return messages.map((message) => DiagnosticMessage(message)).toList();
}
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 9add920..873680b 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -174,7 +174,7 @@
abbr: commonOptions['outputFile'].abbr,
)
..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
-Set values of environment variables. To specify multiple variables, use multiple options or use commas to separate key-value pairs.
+Define an environment declaration. To specify multiple declarations, use multiple options or use commas to separate key-value pairs.
For example, 'dart compile $commandName -Da=1,b=2 main.dart'.''')
..addFlag('enable-asserts',
negatable: false, help: 'Enable assert statements.')
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index fe2f67a..b0296d4 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -189,11 +189,9 @@
}
if (!foundImplicitFileToRun) {
- log.stderr(
- 'Could not find the implicit file to run: '
- 'bin$separator$cwdName.dart.',
- );
- return errorExitCode;
+ // This throws.
+ usageException('Could not find the implicit file to run: '
+ 'bin$separator$cwdName.dart.');
}
}
diff --git a/pkg/dartdev/lib/src/utils.dart b/pkg/dartdev/lib/src/utils.dart
index f77574c..88b80ed 100644
--- a/pkg/dartdev/lib/src/utils.dart
+++ b/pkg/dartdev/lib/src/utils.dart
@@ -56,7 +56,8 @@
allCmds != null &&
args.isNotEmpty &&
allCmds.isNotEmpty &&
- args.firstWhere((arg) => allCmds.contains(arg)) == 'help' &&
+ args.firstWhere((arg) => allCmds.contains(arg), orElse: () => '') ==
+ 'help' &&
args.contains('help') &&
args.contains('pub') &&
args.indexOf('help') + 1 == args.indexOf('pub');
diff --git a/pkg/dartdev/test/commands/analyze_test.dart b/pkg/dartdev/test/commands/analyze_test.dart
index 61206ca..aa4e2eb 100644
--- a/pkg/dartdev/test/commands/analyze_test.dart
+++ b/pkg/dartdev/test/commands/analyze_test.dart
@@ -2,11 +2,13 @@
// 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:dartdev/src/commands/analyze_impl.dart';
import 'package:test/test.dart';
import '../utils.dart';
void main() {
+ group('analysisError', defineAnalysisError, timeout: longTimeout);
group('analyze', defineAnalyze, timeout: longTimeout);
}
@@ -15,6 +17,13 @@
const String _analyzeUsageText =
'Usage: dart analyze [arguments] [<directory>]';
+const String _unusedImportAnalysisOptions = '''
+analyzer:
+ errors:
+ # Increase the severity of several hints.
+ unused_import: warning
+''';
+
const String _unusedImportCodeSnippet = '''
import 'dart:convert';
@@ -23,12 +32,26 @@
}
''';
-const String _unusedImportAnalysisOptions = '''
-analyzer:
- errors:
- # Increase the severity of several hints.
- unused_import: warning
-''';
+void defineAnalysisError() {
+ group('contextMessages', () {
+ test('none', () {
+ var error = AnalysisError({});
+ expect(error.contextMessages, isEmpty);
+ });
+ test('one', () {
+ var error = AnalysisError({
+ 'contextMessages': [<String, dynamic>{}],
+ });
+ expect(error.contextMessages, hasLength(1));
+ });
+ test('two', () {
+ var error = AnalysisError({
+ 'contextMessages': [<String, dynamic>{}, <String, dynamic>{}],
+ });
+ expect(error.contextMessages, hasLength(2));
+ });
+ });
+}
void defineAnalyze() {
TestProject p;
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 38c40c1..5c36e71 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -81,7 +81,7 @@
expect(result.stdout, isEmpty);
expect(result.stderr,
contains('Could not find the implicit file to run: bin'));
- expect(result.exitCode, 255);
+ expect(result.exitCode, 64);
});
test('arguments are properly passed', () {
diff --git a/pkg/dartdev/test/test_all.dart b/pkg/dartdev/test/test_all.dart
index 0c45d45..a3b6db4 100644
--- a/pkg/dartdev/test/test_all.dart
+++ b/pkg/dartdev/test/test_all.dart
@@ -17,6 +17,7 @@
import 'commands/run_test.dart' as run;
import 'commands/test_test.dart' as test;
import 'core_test.dart' as core;
+import 'experiments_test.dart' as experiments;
import 'sdk_test.dart' as sdk;
import 'utils_test.dart' as utils;
@@ -25,6 +26,7 @@
analytics.main();
analyze.main();
create.main();
+ experiments.main();
fix.main();
flag.main();
format.main();
diff --git a/pkg/dartdev/test/utils_test.dart b/pkg/dartdev/test/utils_test.dart
index 31cc6c9..9740dd1 100644
--- a/pkg/dartdev/test/utils_test.dart
+++ b/pkg/dartdev/test/utils_test.dart
@@ -108,6 +108,8 @@
expect(PubUtils.shouldModifyArgs([], null), isFalse);
expect(PubUtils.shouldModifyArgs(null, []), isFalse);
expect(PubUtils.shouldModifyArgs([], []), isFalse);
+ expect(PubUtils.shouldModifyArgs(['-h'], allCmds), isFalse);
+ expect(PubUtils.shouldModifyArgs(['--help'], allCmds), isFalse);
expect(PubUtils.shouldModifyArgs(['help'], allCmds), isFalse);
expect(PubUtils.shouldModifyArgs(['pub'], allCmds), isFalse);
expect(PubUtils.shouldModifyArgs(['analyze', 'help', 'pub'], allCmds),
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 2940119..3a5f05f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1090,7 +1090,7 @@
if (loader.target.context.options
.isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
- valueClass.transformComponent(component);
+ valueClass.transformComponent(component, loader.coreTypes);
ticker.logMs("Lowered value classes");
}
diff --git a/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart
new file mode 100644
index 0000000..0c1ef17
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart
@@ -0,0 +1,12 @@
+main() {
+ // Identifiers can't have non-ascii characters.
+ // Having this comment shouldn't trigger any asserts though.
+ int æFoo = 42;
+ // Try comment on an identifier that doesn't start with a non-ascii char too.
+ int fooÆ = 42;
+ // Try comment on an OK identifier too.
+ int foo = 42;
+ print(/* comment */ æFoo);
+ print(/* comment */ fooÆ);
+ print(/* comment */ foo);
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.expect b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.expect
new file mode 100644
index 0000000..d241e52
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.expect
@@ -0,0 +1,111 @@
+Problems reported:
+
+parser/error_recovery/comment_on_non_ascii_identifier:4:7: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
+ int æFoo = 42;
+ ^
+
+parser/error_recovery/comment_on_non_ascii_identifier:6:10: The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments.
+ int fooÆ = 42;
+ ^
+
+parser/error_recovery/comment_on_non_ascii_identifier:9:23: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
+ print(/* comment */ æFoo);
+ ^
+
+parser/error_recovery/comment_on_non_ascii_identifier:10:26: The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments.
+ print(/* comment */ fooÆ);
+ ^
+
+beginCompilationUnit(main)
+ beginMetadataStar(main)
+ endMetadataStar(0)
+ beginTopLevelMember(main)
+ beginTopLevelMethod(NonAsciiIdentifierToken(198), null)
+ handleNoType(NonAsciiIdentifierToken(198))
+ handleIdentifier(main, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginMetadataStar(int)
+ endMetadataStar(0)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(æFoo)
+ handleType(int, null)
+ beginVariablesDeclaration(æFoo, null, null)
+ handleIdentifier(æFoo, localVariableDeclaration)
+ beginInitializedIdentifier(æFoo)
+ beginVariableInitializer(=)
+ handleLiteralInt(42)
+ endVariableInitializer(=)
+ endInitializedIdentifier(æFoo)
+ endVariablesDeclaration(1, ;)
+ beginMetadataStar(int)
+ endMetadataStar(0)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(fooÆ)
+ handleType(int, null)
+ beginVariablesDeclaration(fooÆ, null, null)
+ handleIdentifier(fooÆ, localVariableDeclaration)
+ beginInitializedIdentifier(fooÆ)
+ beginVariableInitializer(=)
+ handleLiteralInt(42)
+ endVariableInitializer(=)
+ endInitializedIdentifier(fooÆ)
+ endVariablesDeclaration(1, ;)
+ beginMetadataStar(int)
+ endMetadataStar(0)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(foo)
+ handleType(int, null)
+ beginVariablesDeclaration(foo, null, null)
+ handleIdentifier(foo, localVariableDeclaration)
+ beginInitializedIdentifier(foo)
+ beginVariableInitializer(=)
+ handleLiteralInt(42)
+ endVariableInitializer(=)
+ endInitializedIdentifier(foo)
+ endVariablesDeclaration(1, ;)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(æFoo, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(æFoo, ))
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(fooÆ, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(fooÆ, ))
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(foo, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(foo, ))
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ endBlockFunctionBody(6, {, })
+ endTopLevelMethod(main, null, })
+ endTopLevelDeclaration()
+ handleErrorToken(NonAsciiIdentifierToken(230))
+ handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: æ, codePoint: 230}], NonAsciiIdentifierToken(230), NonAsciiIdentifierToken(230))
+ handleErrorToken(NonAsciiIdentifierToken(198))
+ handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: Æ, codePoint: 198}], NonAsciiIdentifierToken(198), NonAsciiIdentifierToken(198))
+ handleErrorToken(NonAsciiIdentifierToken(230))
+ handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: æ, codePoint: 230}], NonAsciiIdentifierToken(230), NonAsciiIdentifierToken(230))
+ handleErrorToken(NonAsciiIdentifierToken(198))
+ handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: Æ, codePoint: 198}], NonAsciiIdentifierToken(198), NonAsciiIdentifierToken(198))
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.intertwined.expect
new file mode 100644
index 0000000..7413d26
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.intertwined.expect
@@ -0,0 +1,234 @@
+parseUnit(NonAsciiIdentifierToken(230))
+ skipErrorTokens(NonAsciiIdentifierToken(230))
+ listener: beginCompilationUnit(main)
+ syntheticPreviousToken(main)
+ parseTopLevelDeclarationImpl(NonAsciiIdentifierToken(198), Instance of 'DirectiveContext')
+ parseMetadataStar(NonAsciiIdentifierToken(198))
+ listener: beginMetadataStar(main)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl(NonAsciiIdentifierToken(198))
+ listener: beginTopLevelMember(main)
+ isReservedKeyword(()
+ parseTopLevelMethod(NonAsciiIdentifierToken(198), null, NonAsciiIdentifierToken(198), Instance of 'NoType', null, main, false)
+ listener: beginTopLevelMethod(NonAsciiIdentifierToken(198), null)
+ listener: handleNoType(NonAsciiIdentifierToken(198))
+ ensureIdentifierPotentiallyRecovered(NonAsciiIdentifierToken(198), topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(main, topLevelFunctionDeclaration)
+ parseMethodTypeVar(main)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(main, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, int)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(æFoo)
+ listener: beginMetadataStar(int)
+ listener: endMetadataStar(0)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(æFoo)
+ listener: handleType(int, null)
+ listener: beginVariablesDeclaration(æFoo, null, null)
+ parseVariablesDeclarationRest(int, true)
+ parseOptionallyInitializedIdentifier(int)
+ ensureIdentifier(int, localVariableDeclaration)
+ listener: handleIdentifier(æFoo, localVariableDeclaration)
+ listener: beginInitializedIdentifier(æFoo)
+ parseVariableInitializerOpt(æFoo)
+ listener: beginVariableInitializer(=)
+ parseExpression(=)
+ parsePrecedenceExpression(=, 1, true)
+ parseUnaryExpression(=, true)
+ parsePrimary(=, expression)
+ parseLiteralInt(=)
+ listener: handleLiteralInt(42)
+ listener: endVariableInitializer(=)
+ listener: endInitializedIdentifier(æFoo)
+ ensureSemicolon(42)
+ listener: endVariablesDeclaration(1, ;)
+ notEofOrValue(}, int)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(fooÆ)
+ listener: beginMetadataStar(int)
+ listener: endMetadataStar(0)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(fooÆ)
+ listener: handleType(int, null)
+ listener: beginVariablesDeclaration(fooÆ, null, null)
+ parseVariablesDeclarationRest(int, true)
+ parseOptionallyInitializedIdentifier(int)
+ ensureIdentifier(int, localVariableDeclaration)
+ listener: handleIdentifier(fooÆ, localVariableDeclaration)
+ listener: beginInitializedIdentifier(fooÆ)
+ parseVariableInitializerOpt(fooÆ)
+ listener: beginVariableInitializer(=)
+ parseExpression(=)
+ parsePrecedenceExpression(=, 1, true)
+ parseUnaryExpression(=, true)
+ parsePrimary(=, expression)
+ parseLiteralInt(=)
+ listener: handleLiteralInt(42)
+ listener: endVariableInitializer(=)
+ listener: endInitializedIdentifier(fooÆ)
+ ensureSemicolon(42)
+ listener: endVariablesDeclaration(1, ;)
+ notEofOrValue(}, int)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(foo)
+ listener: beginMetadataStar(int)
+ listener: endMetadataStar(0)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(foo)
+ listener: handleType(int, null)
+ listener: beginVariablesDeclaration(foo, null, null)
+ parseVariablesDeclarationRest(int, true)
+ parseOptionallyInitializedIdentifier(int)
+ ensureIdentifier(int, localVariableDeclaration)
+ listener: handleIdentifier(foo, localVariableDeclaration)
+ listener: beginInitializedIdentifier(foo)
+ parseVariableInitializerOpt(foo)
+ listener: beginVariableInitializer(=)
+ parseExpression(=)
+ parsePrecedenceExpression(=, 1, true)
+ parseUnaryExpression(=, true)
+ parsePrimary(=, expression)
+ parseLiteralInt(=)
+ listener: handleLiteralInt(42)
+ listener: endVariableInitializer(=)
+ listener: endInitializedIdentifier(foo)
+ ensureSemicolon(42)
+ listener: endVariablesDeclaration(1, ;)
+ notEofOrValue(}, print)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement(;)
+ parseExpression(;)
+ parsePrecedenceExpression(;, 1, true)
+ parseUnaryExpression(;, true)
+ parsePrimary(;, expression)
+ parseSendOrFunctionLiteral(;, expression)
+ looksLikeFunctionBody(;)
+ parseSend(;, expression)
+ ensureIdentifier(;, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(æFoo, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(æFoo)
+ listener: handleNoArguments())
+ listener: handleSend(æFoo, ))
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, print)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement(;)
+ parseExpression(;)
+ parsePrecedenceExpression(;, 1, true)
+ parseUnaryExpression(;, true)
+ parsePrimary(;, expression)
+ parseSendOrFunctionLiteral(;, expression)
+ looksLikeFunctionBody(;)
+ parseSend(;, expression)
+ ensureIdentifier(;, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(fooÆ, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(fooÆ)
+ listener: handleNoArguments())
+ listener: handleSend(fooÆ, ))
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, print)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement(;)
+ parseExpression(;)
+ parsePrecedenceExpression(;, 1, true)
+ parseUnaryExpression(;, true)
+ parsePrimary(;, expression)
+ parseSendOrFunctionLiteral(;, expression)
+ looksLikeFunctionBody(;)
+ parseSend(;, expression)
+ ensureIdentifier(;, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(foo, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(foo)
+ listener: handleNoArguments())
+ listener: handleSend(foo, ))
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(6, {, })
+ listener: endTopLevelMethod(main, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(NonAsciiIdentifierToken(230))
+ listener: handleErrorToken(NonAsciiIdentifierToken(230))
+ listener: handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: æ, codePoint: 230}], NonAsciiIdentifierToken(230), NonAsciiIdentifierToken(230))
+ listener: handleErrorToken(NonAsciiIdentifierToken(198))
+ listener: handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: Æ, codePoint: 198}], NonAsciiIdentifierToken(198), NonAsciiIdentifierToken(198))
+ listener: handleErrorToken(NonAsciiIdentifierToken(230))
+ listener: handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: æ, codePoint: 230}], NonAsciiIdentifierToken(230), NonAsciiIdentifierToken(230))
+ listener: handleErrorToken(NonAsciiIdentifierToken(198))
+ listener: handleRecoverableError(Message[NonAsciiIdentifier, The non-ASCII character 'Æ' (U+00C6) can't be used in identifiers, only in strings and comments., Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)., {character: Æ, codePoint: 198}], NonAsciiIdentifierToken(198), NonAsciiIdentifierToken(198))
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.parser.expect
new file mode 100644
index 0000000..e0dacd4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.parser.expect
@@ -0,0 +1,31 @@
+main() {
+
+
+int æFoo = 42;
+
+int fooÆ = 42;
+
+int foo = 42;
+print( æFoo);
+print( fooÆ);
+print( foo);
+}
+
+[NonAsciiIdentifierToken]
+
+[NonAsciiIdentifierToken]
+
+
+[NonAsciiIdentifierToken]
+[NonAsciiIdentifierToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+
+int[StringToken] æFoo[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+
+int[StringToken] fooÆ[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+
+int[StringToken] foo[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+print[StringToken]([BeginToken] æFoo[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken] fooÆ[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken] foo[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.scanner.expect
new file mode 100644
index 0000000..e0dacd4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/comment_on_non_ascii_identifier.dart.scanner.expect
@@ -0,0 +1,31 @@
+main() {
+
+
+int æFoo = 42;
+
+int fooÆ = 42;
+
+int foo = 42;
+print( æFoo);
+print( fooÆ);
+print( foo);
+}
+
+[NonAsciiIdentifierToken]
+
+[NonAsciiIdentifierToken]
+
+
+[NonAsciiIdentifierToken]
+[NonAsciiIdentifierToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+
+
+int[StringToken] æFoo[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+
+int[StringToken] fooÆ[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+
+int[StringToken] foo[StringToken] =[SimpleToken] 42[StringToken];[SimpleToken]
+print[StringToken]([BeginToken] æFoo[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken] fooÆ[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken] foo[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index e6f10d1..f81b308 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -8,8 +8,10 @@
environment:
sdk: '>=2.2.2 <3.0.0'
dependencies:
- _fe_analyzer_shared: ^2.0.0
- kernel: 0.3.29
+ _fe_analyzer_shared:
+ path: ../_fe_analyzer_shared/
+ kernel:
+ path: ../kernel/
package_config:
path: ../../third_party/pkg_tested/package_config/
dev_dependencies:
diff --git a/pkg/front_end/test/deps_test.dart b/pkg/front_end/test/deps_test.dart
index 64cce4a..3bb12a7 100644
--- a/pkg/front_end/test/deps_test.dart
+++ b/pkg/front_end/test/deps_test.dart
@@ -35,9 +35,10 @@
// TODO(johnniwinther): Fix to allow dependency of package:package_config.
"third_party/pkg_tested/package_config/lib/src/util_io.dart",
- // TODO(CFE-team): This file should not be included.
+ // TODO(CFE-team): These files should not be included.
// The package isn't even in pubspec.yaml.
"pkg/meta/lib/meta.dart",
+ "pkg/meta/lib/meta_meta.dart",
};
Future<void> main() async {
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
index 6b2cbce..969be0d 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class EmptyClass extends core::Object {
synthetic constructor •() → self::EmptyClass
: super core::Object::•()
diff --git a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
index 6b2cbce..969be0d 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.strong.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class EmptyClass extends core::Object {
synthetic constructor •() → self::EmptyClass
: super core::Object::•()
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
index 6b2cbce..969be0d 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class EmptyClass extends core::Object {
synthetic constructor •() → self::EmptyClass
: super core::Object::•()
diff --git a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
index 6b2cbce..969be0d 100644
--- a/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/empty.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class EmptyClass extends core::Object {
synthetic constructor •() → self::EmptyClass
: super core::Object::•()
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
index 34ca526..38e8d0c 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,7 +27,6 @@
: super self::B::•()
;
}
-@#C1
class F = self::B with self::C {
synthetic constructor •() → self::F
: super self::B::•()
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
index b6394fb..1203e0a 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.strong.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,7 +27,6 @@
: super self::B::•()
;
}
-@#C1
class F extends self::B implements self::C /*isEliminatedMixin*/ {
synthetic constructor •() → self::F
: super self::B::•()
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
index 34ca526..38e8d0c 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,7 +27,6 @@
: super self::B::•()
;
}
-@#C1
class F = self::B with self::C {
synthetic constructor •() → self::F
: super self::B::•()
diff --git a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
index b6394fb..1203e0a 100644
--- a/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/explicit_mixin.dart.weak.transformed.expect
@@ -2,7 +2,6 @@
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,7 +27,6 @@
: super self::B::•()
;
}
-@#C1
class F extends self::B implements self::C /*isEliminatedMixin*/ {
synthetic constructor •() → self::F
: super self::B::•()
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart b/pkg/front_end/testcases/value_class/non_final_field_error.dart
index 1cb241b..b9ac3c4 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart
@@ -6,7 +6,7 @@
@valueClass
class Animal {
- int numLegs;
+ int numberOfLegs;
}
main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.outline.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.outline.expect
index 0576b95..2b8fa05 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.outline.expect
@@ -4,7 +4,7 @@
@self::valueClass
class Animal extends core::Object {
- field core::int numLegs;
+ field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
index c424f4f..c7c00ed 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.expect
@@ -2,18 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
index c424f4f..c7c00ed 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.strong.transformed.expect
@@ -2,18 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline.expect
index 2130873..f3e2971 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline.expect
@@ -2,7 +2,7 @@
@valueClass
class Animal {
- int numLegs;
+ int numberOfLegs;
}
main() {}
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline_modelled.expect
index e9bb0a6..8e62800 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.textual_outline_modelled.expect
@@ -1,6 +1,6 @@
@valueClass
class Animal {
- int numLegs;
+ int numberOfLegs;
}
const String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
index c424f4f..c7c00ed 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.expect
@@ -2,18 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
index c424f4f..c7c00ed 100644
--- a/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_final_field_error.dart.weak.transformed.expect
@@ -2,18 +2,17 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/non_final_field_error.dart:9:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart
index 00d89f6..e7ab504 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart
@@ -6,7 +6,7 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat extends Animal {}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.outline.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.outline.expect
index 0dc7afd..df9e66f 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.outline.expect
@@ -4,7 +4,7 @@
@self::valueClass
class Animal extends core::Object {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
index 257657f..8ba63ea 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.expect
@@ -2,19 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
index 257657f..8ba63ea 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.strong.transformed.expect
@@ -2,19 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline.expect
index 91337d4..0394cbe 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline.expect
@@ -2,7 +2,7 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat extends Animal {}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline_modelled.expect
index 693a088..93eb8a7 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.textual_outline_modelled.expect
@@ -1,6 +1,6 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat extends Animal {}
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
index 257657f..8ba63ea 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.expect
@@ -2,19 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
index 257657f..8ba63ea 100644
--- a/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_extends_value_error.dart.weak.transformed.expect
@@ -2,19 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_extends_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends self::Animal {
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart
index ee4bd91..f86c562 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart
@@ -6,11 +6,11 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.outline.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.outline.expect
index 1b24fca..bc92132 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.outline.expect
@@ -4,12 +4,12 @@
@self::valueClass
class Animal extends core::Object {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Cat
;
}
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
index a2359d2..15fac95 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.expect
@@ -2,28 +2,27 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Cat
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
index a2359d2..15fac95 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.strong.transformed.expect
@@ -2,28 +2,27 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Cat
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline.expect
index a28b098..21b0351 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline.expect
@@ -2,11 +2,11 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {}
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline_modelled.expect
index 021adc2..fd4d61a 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.textual_outline_modelled.expect
@@ -1,10 +1,10 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
const String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
index a2359d2..15fac95 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.expect
@@ -2,28 +2,27 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Cat
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
index a2359d2..15fac95 100644
--- a/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/non_value_implements_value_error.dart.weak.transformed.expect
@@ -2,28 +2,27 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/non_value_implements_value_error.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Cat
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/value_class/simple.dart b/pkg/front_end/testcases/value_class/simple.dart
index e781016..c2b4107 100644
--- a/pkg/front_end/testcases/value_class/simple.dart
+++ b/pkg/front_end/testcases/value_class/simple.dart
@@ -6,13 +6,13 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {
- Animal firstAnimal = Animal(numLegs: 4);
- Animal secondAnimal = Animal(numLegs: 4);
- Animal thirdAnimal = Animal(numLegs: 3);
+ Animal firstAnimal = Animal(numberOfLegs: 4);
+ Animal secondAnimal = Animal(numberOfLegs: 4);
+ Animal thirdAnimal = Animal(numberOfLegs: 3);
expect(true, firstAnimal == secondAnimal);
expect(false, firstAnimal == thirdAnimal);
diff --git a/pkg/front_end/testcases/value_class/simple.dart.outline.expect b/pkg/front_end/testcases/value_class/simple.dart.outline.expect
index 03509b9..14f3e52 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.outline.expect
@@ -4,7 +4,7 @@
@self::valueClass
class Animal extends core::Object {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
index 09bd934..c9eb762 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.expect
@@ -2,53 +2,52 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
-// Animal firstAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal firstAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
-// Animal secondAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+// Animal secondAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
-// Animal thirdAnimal = Animal(numLegs: 3);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal thirdAnimal = Animal(numberOfLegs: 3);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
- Animal firstAnimal = Animal(numLegs: 4);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
- self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
- Animal secondAnimal = Animal(numLegs: 4);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
- self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
- Animal thirdAnimal = Animal(numLegs: 3);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal firstAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+ Animal secondAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal thirdAnimal = Animal(numberOfLegs: 3);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
self::expect(true, firstAnimal.{core::Object::==}(secondAnimal));
self::expect(false, firstAnimal.{core::Object::==}(thirdAnimal));
self::expect(true, firstAnimal.{core::Object::hashCode}.{core::num::==}(secondAnimal.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
index 535162a..344eb6f 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.strong.transformed.expect
@@ -2,53 +2,52 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
-// Animal firstAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal firstAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
-// Animal secondAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+// Animal secondAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
-// Animal thirdAnimal = Animal(numLegs: 3);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal thirdAnimal = Animal(numberOfLegs: 3);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
- Animal firstAnimal = Animal(numLegs: 4);
- ^^^^^^^";
- self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
- Animal secondAnimal = Animal(numLegs: 4);
- ^^^^^^^";
- self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
- Animal thirdAnimal = Animal(numLegs: 3);
- ^^^^^^^";
+ self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal firstAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^";
+ self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+ Animal secondAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^";
+ self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal thirdAnimal = Animal(numberOfLegs: 3);
+ ^^^^^^^^^^^^";
self::expect(true, firstAnimal.{core::Object::==}(secondAnimal));
self::expect(false, firstAnimal.{core::Object::==}(thirdAnimal));
self::expect(true, firstAnimal.{core::Object::hashCode}.{core::num::==}(secondAnimal.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/simple.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/simple.dart.textual_outline.expect
index 5408535..318ea62 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.textual_outline.expect
@@ -2,7 +2,7 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {}
diff --git a/pkg/front_end/testcases/value_class/simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/simple.dart.textual_outline_modelled.expect
index dabb2ae..05032a9 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.textual_outline_modelled.expect
@@ -1,6 +1,6 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
const String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
index 09bd934..c9eb762 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.expect
@@ -2,53 +2,52 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
-// Animal firstAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal firstAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
-// Animal secondAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+// Animal secondAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
-// Animal thirdAnimal = Animal(numLegs: 3);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal thirdAnimal = Animal(numberOfLegs: 3);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
- Animal firstAnimal = Animal(numLegs: 4);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
- self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
- Animal secondAnimal = Animal(numLegs: 4);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
- self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
- Animal thirdAnimal = Animal(numLegs: 3);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal firstAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+ Animal secondAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
+ self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal thirdAnimal = Animal(numberOfLegs: 3);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Animal;
self::expect(true, firstAnimal.{core::Object::==}(secondAnimal));
self::expect(false, firstAnimal.{core::Object::==}(thirdAnimal));
self::expect(true, firstAnimal.{core::Object::hashCode}.{core::num::==}(secondAnimal.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
index 535162a..344eb6f 100644
--- a/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/simple.dart.weak.transformed.expect
@@ -2,53 +2,52 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
-// Animal firstAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal firstAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
-// Animal secondAnimal = Animal(numLegs: 4);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+// Animal secondAnimal = Animal(numberOfLegs: 4);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
-// Animal thirdAnimal = Animal(numLegs: 3);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+// Animal thirdAnimal = Animal(numberOfLegs: 3);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/simple.dart:8:7: Context: The class 'Animal' has a constructor that takes no arguments.
// class Animal {
// ^
//
-// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/simple.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numLegs'.
- Animal firstAnimal = Animal(numLegs: 4);
- ^^^^^^^";
- self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numLegs'.
- Animal secondAnimal = Animal(numLegs: 4);
- ^^^^^^^";
- self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numLegs'.
- Animal thirdAnimal = Animal(numLegs: 3);
- ^^^^^^^";
+ self::Animal firstAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:13:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal firstAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^";
+ self::Animal secondAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:14:32: Error: No named parameter with the name 'numberOfLegs'.
+ Animal secondAnimal = Animal(numberOfLegs: 4);
+ ^^^^^^^^^^^^";
+ self::Animal thirdAnimal = invalid-expression "pkg/front_end/testcases/value_class/simple.dart:15:31: Error: No named parameter with the name 'numberOfLegs'.
+ Animal thirdAnimal = Animal(numberOfLegs: 3);
+ ^^^^^^^^^^^^";
self::expect(true, firstAnimal.{core::Object::==}(secondAnimal));
self::expect(false, firstAnimal.{core::Object::==}(thirdAnimal));
self::expect(true, firstAnimal.{core::Object::hashCode}.{core::num::==}(secondAnimal.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/super_type.dart b/pkg/front_end/testcases/value_class/super_type.dart
index 4182161..10dad24 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart
+++ b/pkg/front_end/testcases/value_class/super_type.dart
@@ -6,19 +6,19 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
- final int numWhiskers;
+ final int numberOfLegs;
+ final int numberOfWhiskers;
}
main() {
- Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
- Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
- Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
+ Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
expect(true, firstCat == secondCat);
expect(false, firstCat == thirdCat);
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.outline.expect b/pkg/front_end/testcases/value_class/super_type.dart.outline.expect
index 1f378c2..5256842 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.outline.expect
@@ -4,14 +4,14 @@
@self::valueClass
class Animal extends core::Object {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
@self::valueClass
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs;
- final field core::int numWhiskers;
+ final field core::int numberOfLegs;
+ final field core::int numberOfWhiskers;
synthetic constructor •() → self::Cat
;
}
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.strong.expect b/pkg/front_end/testcases/value_class/super_type.dart.strong.expect
index ed5ed73..63760688 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.strong.expect
@@ -2,71 +2,69 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
-// Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
-// Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+// Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
-// Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numWhiskers' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numWhiskers;
-// ^^^^^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- final field core::int numWhiskers = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
- Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
- self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
- Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
- self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
- Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+ Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
self::expect(true, firstCat.{core::Object::==}(secondCat));
self::expect(false, firstCat.{core::Object::==}(thirdCat));
self::expect(true, firstCat.{core::Object::hashCode}.{core::num::==}(secondCat.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/super_type.dart.strong.transformed.expect
index b21e4ae..fdbcb96 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.strong.transformed.expect
@@ -2,71 +2,69 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
-// Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
-// Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+// Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
-// Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numWhiskers' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numWhiskers;
-// ^^^^^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- final field core::int numWhiskers = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
- Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^";
- self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
- Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^";
- self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
- Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
- ^^^^^^^";
+ self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^";
+ self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+ Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^";
+ self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+ ^^^^^^^^^^^^";
self::expect(true, firstCat.{core::Object::==}(secondCat));
self::expect(false, firstCat.{core::Object::==}(thirdCat));
self::expect(true, firstCat.{core::Object::hashCode}.{core::num::==}(secondCat.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/super_type.dart.textual_outline.expect
index 08894f3..027fa5d 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.textual_outline.expect
@@ -2,13 +2,13 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
- final int numWhiskers;
+ final int numberOfLegs;
+ final int numberOfWhiskers;
}
main() {}
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/super_type.dart.textual_outline_modelled.expect
index 33c1c4f..7b66670 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.textual_outline_modelled.expect
@@ -1,12 +1,12 @@
@valueClass
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
- final int numWhiskers;
+ final int numberOfLegs;
+ final int numberOfWhiskers;
}
const String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.weak.expect b/pkg/front_end/testcases/value_class/super_type.dart.weak.expect
index ed5ed73..63760688 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.weak.expect
@@ -2,71 +2,69 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
-// Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
-// Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+// Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
-// Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numWhiskers' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numWhiskers;
-// ^^^^^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- final field core::int numWhiskers = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
- Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
- self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
- Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
- self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
- Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
- ^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+ Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
+ self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+ ^^^^^^^^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} self::Cat;
self::expect(true, firstCat.{core::Object::==}(secondCat));
self::expect(false, firstCat.{core::Object::==}(thirdCat));
self::expect(true, firstCat.{core::Object::hashCode}.{core::num::==}(secondCat.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/super_type.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/super_type.dart.weak.transformed.expect
index b21e4ae..fdbcb96 100644
--- a/pkg/front_end/testcases/value_class/super_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/super_type.dart.weak.transformed.expect
@@ -2,71 +2,69 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
-// Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
-// Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+// Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
-// Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+// Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+// ^^^^^^^^^^^^
// pkg/front_end/testcases/value_class/super_type.dart:13:7: Context: The class 'Cat' has a constructor that takes no arguments.
// class Cat implements Animal {
// ^
//
-// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:9:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:14:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numWhiskers' is not initialized.
+// pkg/front_end/testcases/value_class/super_type.dart:15:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numWhiskers;
-// ^^^^^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
-@#C1
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- final field core::int numWhiskers = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfLegs, required core::int numberOfWhiskers}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, self::Cat::numberOfWhiskers = numberOfWhiskers, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
static method main() → dynamic {
- self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numLegs'.
- Cat firstCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^";
- self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numLegs'.
- Cat secondCat = Cat(numLegs: 4, numWhiskers: 10);
- ^^^^^^^";
- self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numLegs'.
- Cat thirdCat = Cat(numLegs: 4, numWhiskers: 0);
- ^^^^^^^";
+ self::Cat firstCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:19:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat firstCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^";
+ self::Cat secondCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:20:23: Error: No named parameter with the name 'numberOfLegs'.
+ Cat secondCat = Cat(numberOfLegs: 4, numberOfWhiskers: 10);
+ ^^^^^^^^^^^^";
+ self::Cat thirdCat = invalid-expression "pkg/front_end/testcases/value_class/super_type.dart:21:22: Error: No named parameter with the name 'numberOfLegs'.
+ Cat thirdCat = Cat(numberOfLegs: 4, numberOfWhiskers: 0);
+ ^^^^^^^^^^^^";
self::expect(true, firstCat.{core::Object::==}(secondCat));
self::expect(false, firstCat.{core::Object::==}(thirdCat));
self::expect(true, firstCat.{core::Object::hashCode}.{core::num::==}(secondCat.{core::Object::hashCode}));
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart b/pkg/front_end/testcases/value_class/value_extends_non_value.dart
index 96bbf65..141c492 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart
@@ -5,10 +5,13 @@
const String valueClass = "valueClass";
class Animal {
- final int numLegs;
+ final int numberOfLegs;
+ Animal({required this.numberOfLegs});
}
@valueClass
-class Cat extends Animal {}
+class Cat extends Animal {
+ final int numberOfWhiskers;
+}
main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.outline.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.outline.expect
index c0cd3b6..f21b790e 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.outline.expect
@@ -3,12 +3,13 @@
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs;
- synthetic constructor •() → self::Animal
+ final field core::int numberOfLegs;
+ constructor •({required core::int numberOfLegs}) → self::Animal
;
}
@self::valueClass
class Cat extends self::Animal {
+ final field core::int numberOfWhiskers;
synthetic constructor •() → self::Cat
;
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
index a196b35..bb987c0 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.expect
@@ -2,29 +2,30 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_extends_non_value.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs;
+ constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
- synthetic constructor •() → self::Cat
- : super self::Animal::•()
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
;
}
-static const field core::String valueClass = #C1;
+static const field core::String valueClass = #C2;
static method main() → dynamic {}
constants {
- #C1 = "valueClass"
+ #C1 = null
+ #C2 = "valueClass"
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
index a196b35..bb987c0 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.strong.transformed.expect
@@ -2,29 +2,30 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_extends_non_value.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs;
+ constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
- synthetic constructor •() → self::Cat
- : super self::Animal::•()
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
;
}
-static const field core::String valueClass = #C1;
+static const field core::String valueClass = #C2;
static method main() → dynamic {}
constants {
- #C1 = "valueClass"
+ #C1 = null
+ #C2 = "valueClass"
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline.expect
index ec2d5db..2f604a3 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline.expect
@@ -1,10 +1,13 @@
const String valueClass = "valueClass";
class Animal {
- final int numLegs;
+ final int numberOfLegs;
+ Animal({required this.numberOfLegs});
}
@valueClass
-class Cat extends Animal {}
+class Cat extends Animal {
+ final int numberOfWhiskers;
+}
main() {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline_modelled.expect
index e50bc0f..777086a 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.textual_outline_modelled.expect
@@ -1,9 +1,12 @@
class Animal {
- final int numLegs;
+ Animal({required this.numberOfLegs});
+ final int numberOfLegs;
}
@valueClass
-class Cat extends Animal {}
+class Cat extends Animal {
+ final int numberOfWhiskers;
+}
const String valueClass = "valueClass";
main() {}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
index a196b35..bb987c0 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.expect
@@ -2,29 +2,30 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_extends_non_value.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs;
+ constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
- synthetic constructor •() → self::Cat
- : super self::Animal::•()
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
;
}
-static const field core::String valueClass = #C1;
+static const field core::String valueClass = #C2;
static method main() → dynamic {}
constants {
- #C1 = "valueClass"
+ #C1 = null
+ #C2 = "valueClass"
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
index a196b35..bb987c0 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value.dart.weak.transformed.expect
@@ -2,29 +2,30 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_extends_non_value.dart:14:13: Error: Final field 'numberOfWhiskers' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfWhiskers;
+// ^^^^^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Animal
- : super core::Object::•()
+ final field core::int numberOfLegs;
+ constructor •({required core::int numberOfLegs = #C1}) → self::Animal
+ : self::Animal::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
- synthetic constructor •() → self::Cat
- : super self::Animal::•()
+ final field core::int numberOfWhiskers = null;
+ synthetic constructor •({required core::int numberOfWhiskers, core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfWhiskers = numberOfWhiskers, super self::Animal::•(numberOfLegs)
;
}
-static const field core::String valueClass = #C1;
+static const field core::String valueClass = #C2;
static method main() → dynamic {}
constants {
- #C1 = "valueClass"
+ #C1 = null
+ #C2 = "valueClass"
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart
index bb077de..2f58313 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart
@@ -5,7 +5,7 @@
const String valueClass = "valueClass";
class Animal {
- int numLegs;
+ int numberOfLegs;
}
@valueClass
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.outline.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.outline.expect
index 7d29b32..05499cb 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.outline.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
class Animal extends core::Object {
- field core::int numLegs;
+ field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
index e0188c9..9c469b8 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.expect
@@ -2,20 +2,19 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- field core::int numLegs = null;
+ field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
: super self::Animal::•()
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
index e0188c9..9c469b8 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.strong.transformed.expect
@@ -2,20 +2,19 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- field core::int numLegs = null;
+ field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
: super self::Animal::•()
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline.expect
index 5d5b409..a670dab 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline.expect
@@ -1,7 +1,7 @@
const String valueClass = "valueClass";
class Animal {
- int numLegs;
+ int numberOfLegs;
}
@valueClass
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline_modelled.expect
index d7e499c..d4c74c2 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.textual_outline_modelled.expect
@@ -1,5 +1,5 @@
class Animal {
- int numLegs;
+ int numberOfLegs;
}
@valueClass
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
index e0188c9..9c469b8 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.expect
@@ -2,20 +2,19 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- field core::int numLegs = null;
+ field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
: super self::Animal::•()
diff --git a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
index e0188c9..9c469b8 100644
--- a/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_extends_non_value_error.dart.weak.transformed.expect
@@ -2,20 +2,19 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numLegs' should be initialized because its type 'int' doesn't allow null.
-// int numLegs;
-// ^^^^^^^
+// pkg/front_end/testcases/value_class/value_extends_non_value_error.dart:8:7: Error: Field 'numberOfLegs' should be initialized because its type 'int' doesn't allow null.
+// int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- field core::int numLegs = null;
+ field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends self::Animal {
synthetic constructor •() → self::Cat
: super self::Animal::•()
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart b/pkg/front_end/testcases/value_class/value_implements_non_value.dart
index cf2c4b0..e75c70d 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart
@@ -5,12 +5,12 @@
const String valueClass = "valueClass";
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.outline.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.outline.expect
index e4fba11..ed5f98c 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.outline.expect
@@ -3,13 +3,13 @@
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Animal
;
}
@self::valueClass
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs;
+ final field core::int numberOfLegs;
synthetic constructor •() → self::Cat
;
}
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
index 549053c..9b0e0a3 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.expect
@@ -2,30 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
index 549053c..9b0e0a3 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.strong.transformed.expect
@@ -2,30 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline.expect
index c0ada4f..193bb7e 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline.expect
@@ -1,12 +1,12 @@
const String valueClass = "valueClass";
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
main() {}
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline_modelled.expect
index 650aa4b..c6763aa 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.textual_outline_modelled.expect
@@ -1,10 +1,10 @@
class Animal {
- final int numLegs;
+ final int numberOfLegs;
}
@valueClass
class Cat implements Animal {
- final int numLegs;
+ final int numberOfLegs;
}
const String valueClass = "valueClass";
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
index 549053c..9b0e0a3 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.expect
@@ -2,30 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
index 549053c..9b0e0a3 100644
--- a/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_implements_non_value.dart.weak.transformed.expect
@@ -2,30 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:8:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numLegs' is not initialized.
+// pkg/front_end/testcases/value_class/value_implements_non_value.dart:13:13: Error: Final field 'numberOfLegs' is not initialized.
// Try to initialize the field in the declaration or in every constructor.
-// final int numLegs;
-// ^^^^^^^
+// final int numberOfLegs;
+// ^^^^^^^^^^^^
//
import self as self;
import "dart:core" as core;
class Animal extends core::Object {
- final field core::int numLegs = null;
+ final field core::int numberOfLegs = null;
synthetic constructor •() → self::Animal
: super core::Object::•()
;
}
-@#C1
class Cat extends core::Object implements self::Animal {
- final field core::int numLegs = null;
- synthetic constructor •() → self::Cat
- : super core::Object::•()
+ final field core::int numberOfLegs = null;
+ synthetic constructor •({required core::int numberOfLegs}) → self::Cat
+ : self::Cat::numberOfLegs = numberOfLegs, super core::Object::•()
;
}
static const field core::String valueClass = #C1;
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart b/pkg/front_end/testcases/value_class/value_mixin_error.dart
index 22c8a1f..3cf32a7 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart
@@ -10,6 +10,6 @@
class B {}
class C extends B with A {} // error, value class as mixin
-class C extends A with B {} // error, C extends a value class
+class D extends A with B {} // error, D extends a value class
main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.outline.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.outline.expect
index a5b1239..4ccaf3a 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.outline.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.outline.expect
@@ -1,14 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:13:7: Error: 'C' is already declared in this scope.
-// class C extends A with B {} // error, C extends a value class
-// ^
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:12:7: Context: Previous declaration of 'C'.
-// class C extends B with A {} // error, value class as mixin
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -26,19 +16,19 @@
: super self::B::•()
;
}
-class C#1 extends self::_C&A&B {
- synthetic constructor •() → self::C#1
- ;
-}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
;
}
-abstract class _C&A&B = self::A with self::B /*isAnonymousMixin*/ {
- synthetic constructor •() → self::_C&A&B
+abstract class _D&A&B = self::A with self::B /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_D&A&B
: super self::A::•()
;
}
+class D extends self::_D&A&B {
+ synthetic constructor •() → self::D
+ ;
+}
static const field core::String valueClass = "valueClass";
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
index 46047b4..cc2aea2 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.expect
@@ -1,18 +1,7 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:13:7: Error: 'C' is already declared in this scope.
-// class C extends A with B {} // error, C extends a value class
-// ^
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:12:7: Context: Previous declaration of 'C'.
-// class C extends B with A {} // error, value class as mixin
-// ^
-//
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,21 +17,21 @@
: super self::B::•()
;
}
-class C#1 extends self::_C&A&B {
- synthetic constructor •() → self::C#1
- : super self::_C&A&B::•()
- ;
-}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
: super self::_C&B&A::•()
;
}
-abstract class _C&A&B = self::A with self::B /*isAnonymousMixin*/ {
- synthetic constructor •() → self::_C&A&B
+abstract class _D&A&B = self::A with self::B /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_D&A&B
: super self::A::•()
;
}
+class D extends self::_D&A&B {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+}
static const field core::String valueClass = #C1;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
index 0a9c8b9..5382fce 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.strong.transformed.expect
@@ -1,18 +1,7 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:13:7: Error: 'C' is already declared in this scope.
-// class C extends A with B {} // error, C extends a value class
-// ^
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:12:7: Context: Previous declaration of 'C'.
-// class C extends B with A {} // error, value class as mixin
-// ^
-//
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,21 +17,21 @@
: super self::B::•()
;
}
-class C#1 extends self::_C&A&B {
- synthetic constructor •() → self::C#1
- : super self::_C&A&B::•()
- ;
-}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
: super self::_C&B&A::•()
;
}
-abstract class _C&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin*/ {
- synthetic constructor •() → self::_C&A&B
+abstract class _D&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin*/ {
+ synthetic constructor •() → self::_D&A&B
: super self::A::•()
;
}
+class D extends self::_D&A&B {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+}
static const field core::String valueClass = #C1;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline.expect
index c195f72..811ccf9 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline.expect
@@ -7,6 +7,6 @@
class C extends B with A {}
-class C extends A with B {}
+class D extends A with B {}
main() {}
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline_modelled.expect
index 17460dc..f9ac261 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.textual_outline_modelled.expect
@@ -3,9 +3,9 @@
class B {}
-class C extends A with B {}
-
class C extends B with A {}
+class D extends A with B {}
+
const String valueClass = "valueClass";
main() {}
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
index 46047b4..cc2aea2 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.expect
@@ -1,18 +1,7 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:13:7: Error: 'C' is already declared in this scope.
-// class C extends A with B {} // error, C extends a value class
-// ^
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:12:7: Context: Previous declaration of 'C'.
-// class C extends B with A {} // error, value class as mixin
-// ^
-//
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,21 +17,21 @@
: super self::B::•()
;
}
-class C#1 extends self::_C&A&B {
- synthetic constructor •() → self::C#1
- : super self::_C&A&B::•()
- ;
-}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
: super self::_C&B&A::•()
;
}
-abstract class _C&A&B = self::A with self::B /*isAnonymousMixin*/ {
- synthetic constructor •() → self::_C&A&B
+abstract class _D&A&B = self::A with self::B /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_D&A&B
: super self::A::•()
;
}
+class D extends self::_D&A&B {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+}
static const field core::String valueClass = #C1;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
index 0a9c8b9..5382fce 100644
--- a/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/value_class/value_mixin_error.dart.weak.transformed.expect
@@ -1,18 +1,7 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:13:7: Error: 'C' is already declared in this scope.
-// class C extends A with B {} // error, C extends a value class
-// ^
-// pkg/front_end/testcases/value_class/value_mixin_error.dart:12:7: Context: Previous declaration of 'C'.
-// class C extends B with A {} // error, value class as mixin
-// ^
-//
import self as self;
import "dart:core" as core;
-@#C1
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
@@ -28,21 +17,21 @@
: super self::B::•()
;
}
-class C#1 extends self::_C&A&B {
- synthetic constructor •() → self::C#1
- : super self::_C&A&B::•()
- ;
-}
class C extends self::_C&B&A {
synthetic constructor •() → self::C
: super self::_C&B&A::•()
;
}
-abstract class _C&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin*/ {
- synthetic constructor •() → self::_C&A&B
+abstract class _D&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin*/ {
+ synthetic constructor •() → self::_D&A&B
: super self::A::•()
;
}
+class D extends self::_D&A&B {
+ synthetic constructor •() → self::D
+ : super self::_D&A&B::•()
+ ;
+}
static const field core::String valueClass = #C1;
static method main() → dynamic {}
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index cc0577e..4b3acb0 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -6,11 +6,186 @@
import '../ast.dart';
import '../kernel.dart';
-import '../visitor.dart';
+import '../core_types.dart' show CoreTypes;
-Component transformComponent(Component component) {
- new ValueClassTransformer().visitComponent(component);
- return component;
+void transformComponent(Component node, CoreTypes coreTypes) {
+ for (Library library in node.libraries) {
+ for (Class cls in library.classes) {
+ if (isValueClass(cls)) {
+ transformValueClass(cls, coreTypes);
+ }
+ }
+ }
}
-class ValueClassTransformer extends Transformer {}
+void transformValueClass(Class cls, CoreTypes coreTypes) {
+ addConstructor(cls, coreTypes);
+ // addEqualsOperator(cls, coreTypes);
+ // addHashCode(cls, coreTypes);
+ // addCopyWith(cls);
+}
+
+void addConstructor(Class cls, CoreTypes coreTypes) {
+ Constructor superConstructor = null;
+ for (Constructor constructor in cls.superclass.constructors) {
+ if (constructor.name.name == "") {
+ superConstructor = constructor;
+ }
+ }
+ Constructor syntheticConstructor = null;
+ for (Constructor constructor in cls.constructors) {
+ if (constructor.isSynthetic) {
+ syntheticConstructor = constructor;
+ }
+ }
+
+ List<VariableDeclaration> superParameters = superConstructor
+ .function.namedParameters
+ .map<VariableDeclaration>((e) => VariableDeclaration(e.name, type: e.type)
+ ..parent = syntheticConstructor.function)
+ .toList();
+ Map<String, VariableDeclaration> ownFields = Map.fromIterable(cls.fields,
+ key: (f) => f.name.name,
+ value: (f) =>
+ VariableDeclaration(f.name.name, type: f.type, isRequired: true)
+ ..parent = syntheticConstructor.function);
+
+ List<Initializer> initializersConstructor = cls.fields
+ .map<Initializer>((f) =>
+ FieldInitializer(f, VariableGet(ownFields[f.name.name]))
+ ..parent = syntheticConstructor)
+ .toList();
+
+ initializersConstructor.add(SuperInitializer(superConstructor,
+ Arguments(superParameters.map((f) => VariableGet(f)).toList()))
+ ..parent = syntheticConstructor);
+
+ syntheticConstructor.function.namedParameters
+ ..clear()
+ ..addAll(ownFields.values)
+ ..addAll(superParameters);
+ syntheticConstructor.initializers = initializersConstructor;
+
+ int valueClassAnnotationIndex;
+ for (int annotationIndex = 0;
+ annotationIndex < cls.annotations.length;
+ annotationIndex++) {
+ Expression annotation = cls.annotations[annotationIndex];
+ if (annotation is ConstantExpression &&
+ annotation.constant is StringConstant) {
+ StringConstant constant = annotation.constant;
+ if (constant.value == 'valueClass') {
+ valueClassAnnotationIndex = annotationIndex;
+ }
+ }
+ }
+ cls.annotations.removeAt(valueClassAnnotationIndex);
+}
+/*
+
+void addEqualsOperator(Class cls, CoreTypes coreTypes) {
+ Map<String, VariableDeclaration> environment = Map.fromIterable(cls.fields,
+ key: (f) => f.name.name,
+ value: (f) => VariableDeclaration(f.name.name, type: f.type));
+
+ VariableDeclaration other = VariableDeclaration("other");
+
+ var retType = cls.enclosingLibrary.isNonNullableByDefault
+ ? coreTypes.boolNonNullableRawType
+ : coreTypes.boolLegacyRawType;
+ var myType = coreTypes.thisInterfaceType(cls, Nullability.nonNullable);
+
+ cls.addMember(Procedure(
+ Name("=="),
+ ProcedureKind.Operator,
+ FunctionNode(
+ ReturnStatement(ConditionalExpression(
+ IsExpression(VariableGet(other), myType),
+ cls.fields
+ .map((f) => MethodInvocation(
+ PropertyGet(ThisExpression(), f.name, f),
+ Name('=='),
+ Arguments([
+ PropertyGet(VariableGet(other, myType), f.name, f)
+ ])))
+ .toList()
+ .fold(
+ BoolLiteral(true),
+ (previousValue, element) =>
+ LogicalExpression(previousValue, '&&', element)),
+ BoolLiteral(false),
+ retType)),
+ returnType: retType,
+ positionalParameters: [other])));
+}
+
+void addHashCode(Class cls, CoreTypes coreTypes) {
+ Map<String, VariableDeclaration> environment = Map.fromIterable(cls.fields,
+ key: (f) => f.name.name,
+ value: (f) => VariableDeclaration(f.name.name, type: f.type));
+
+ VariableDeclaration other = VariableDeclaration("other");
+
+ var retType = cls.enclosingLibrary.isNonNullableByDefault
+ ? coreTypes.boolNonNullableRawType
+ : coreTypes.boolLegacyRawType;
+
+ cls.addMember(Procedure(
+ Name("hashCode"),
+ ProcedureKind.Getter,
+ FunctionNode(ReturnStatement(cls.fields
+ .map((f) => DirectPropertyGet(
+ VariableGet(environment[f.name.name]),
+ Procedure(Name("hashCode"), ProcedureKind.Getter,
+ null) // TODO(jlcontreras): Add ref to the real hashCode getter, dont create a new one
+ ))
+ .toList()
+ .fold(
+ IntLiteral(0),
+ (previousValue, element) => MethodInvocation(
+ previousValue, Name("*"), Arguments([element])))))));
+}
+
+void addCopyWith(Class cls) {
+ Map<String, VariableDeclaration> environment = Map.fromIterable(cls.fields,
+ key: (f) => f.name.name,
+ value: (f) => VariableDeclaration(f.name.name, type: f.type));
+
+ Constructor syntheticConstructor = null;
+ for (Constructor constructor in cls.constructors) {
+ if (constructor.isSynthetic) {
+ syntheticConstructor = constructor;
+ }
+ }
+
+ cls.addMember(Procedure(
+ Name("copyWith"),
+ ProcedureKind.Method,
+ FunctionNode(
+ ReturnStatement(ConstructorInvocation(
+ syntheticConstructor,
+ Arguments(cls.fields
+ .map((f) => ConditionalExpression(
+ MethodInvocation(VariableGet(environment[f.name.name]),
+ Name('=='), Arguments([NullLiteral()])),
+ PropertyGet(ThisExpression(), f.name, f),
+ VariableGet(environment[f.name.name]),
+ f.type))
+ .toList()))),
+ namedParameters:
+ cls.fields.map((f) => environment[f.name.name]).toList())));
+}
+*/
+
+bool isValueClass(Class cls) {
+ for (Expression annotation in cls.annotations) {
+ if (annotation is ConstantExpression &&
+ annotation.constant is StringConstant) {
+ StringConstant constant = annotation.constant;
+ if (constant.value == 'valueClass') {
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index b123407..11652e1 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -19,6 +19,8 @@
/// language tour.
library meta;
+import 'meta_meta.dart';
+
/// Used to annotate a function `f`. Indicates that `f` always throws an
/// exception. Any functions that override `f`, in class inheritance, are also
/// expected to conform to this contract.
@@ -305,6 +307,13 @@
const _Checked();
}
+@Target({
+ TargetKind.classType,
+ TargetKind.function,
+ TargetKind.getter,
+ TargetKind.library,
+ TargetKind.method,
+})
class _DoNotStore {
const _DoNotStore();
}
diff --git a/pkg/test_runner/analysis_options.yaml b/pkg/test_runner/analysis_options.yaml
index c452209..788c451 100644
--- a/pkg/test_runner/analysis_options.yaml
+++ b/pkg/test_runner/analysis_options.yaml
@@ -5,10 +5,8 @@
rules:
# TODO: Enable these once the existing violations have been fixed.
# - annotate_overrides
-# - avoid_renaming_method_parameters
# - non_constant_identifier_names
# - only_throw_errors
-# - prefer_initializing_formals
# - prefer_interpolation_to_compose_strings
# - prefer_is_empty
# - prefer_is_not_empty
@@ -19,6 +17,7 @@
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_relative_lib_imports
+ - avoid_renaming_method_parameters
- avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_void
@@ -60,6 +59,7 @@
- prefer_equal_for_default_values
- prefer_final_fields
- prefer_generic_function_type_aliases
+ - prefer_initializing_formals
- prefer_null_aware_operators
- prefer_typing_uninitialized_variables
- recursive_getters
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index f2804c5..75a89ad 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -815,11 +815,8 @@
if (_currentStartingBrowserId == id) _currentStartingBrowserId = null;
}
- BrowserTestRunner(
- TestConfiguration configuration, String localIp, this.maxNumBrowsers)
- : configuration = configuration,
- localIp = localIp,
- testingServer = BrowserTestingServer(configuration, localIp,
+ BrowserTestRunner(this.configuration, this.localIp, this.maxNumBrowsers)
+ : testingServer = BrowserTestingServer(configuration, localIp,
Browser.requiresFocus(configuration.runtime.name)) {
testingServer.testRunner = this;
}
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index ae9fb11..348ae03 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -502,11 +502,10 @@
final String dartFile;
final bool checked;
- VMBatchCommand(String executable, String dartFile, List<String> arguments,
+ VMBatchCommand(String executable, this.dartFile, List<String> arguments,
Map<String, String> environmentOverrides,
{this.checked = true, int index = 0})
- : dartFile = dartFile,
- super('vm-batch', executable, arguments, environmentOverrides, null,
+ : super('vm-batch', executable, arguments, environmentOverrides, null,
index);
VMBatchCommand indexedCopy(int index) =>
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 935a637..6b08ea0 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -307,14 +307,16 @@
: super._subclass(configuration);
CommandArtifact computeCompilationArtifact(String tempDir,
- List<String> globalArguments, Map<String, String> environmentOverrides) {
+ List<String> arguments, Map<String, String> environmentOverrides) {
var allCommands = <Command>[];
// The first compilation command is as usual.
- var arguments = pipelineCommands[0].extractArguments(globalArguments, null);
+ var compileArguments =
+ pipelineCommands[0].extractArguments(arguments, null);
var artifact = pipelineCommands[0]
.compilerConfiguration
- .computeCompilationArtifact(tempDir, arguments, environmentOverrides);
+ .computeCompilationArtifact(
+ tempDir, compileArguments, environmentOverrides);
allCommands.addAll(artifact.commands);
// The following compilation commands are based on the output of the
@@ -322,9 +324,9 @@
for (var i = 1; i < pipelineCommands.length; i++) {
var command = pipelineCommands[i];
- arguments = command.extractArguments(globalArguments, artifact.filename);
- artifact = command.compilerConfiguration
- .computeCompilationArtifact(tempDir, arguments, environmentOverrides);
+ compileArguments = command.extractArguments(arguments, artifact.filename);
+ artifact = command.compilerConfiguration.computeCompilationArtifact(
+ tempDir, compileArguments, environmentOverrides);
allCommands.addAll(artifact.commands);
}
@@ -564,8 +566,8 @@
workingDirectory: inputDir);
}
- CommandArtifact computeCompilationArtifact(
- String tempDir, List<String> arguments, Map<String, String> environment) {
+ CommandArtifact computeCompilationArtifact(String tempDir,
+ List<String> arguments, Map<String, String> environmentOverrides) {
// The list of arguments comes from a call to our own
// computeCompilerArguments(). It contains the shared options followed by
// the input file path.
@@ -576,10 +578,9 @@
var inputFilename = Uri.file(inputFile).pathSegments.last;
var outputFile = "$tempDir/${inputFilename.replaceAll('.dart', '.js')}";
- return CommandArtifact(
- [_createCommand(inputFile, outputFile, sharedOptions, environment)],
- outputFile,
- "application/javascript");
+ return CommandArtifact([
+ _createCommand(inputFile, outputFile, sharedOptions, environmentOverrides)
+ ], outputFile, "application/javascript");
}
}
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index ad3f498..cb2c9c4 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -303,7 +303,7 @@
class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
final bool useElf;
- DartPrecompiledRuntimeConfiguration({bool useElf}) : useElf = useElf;
+ DartPrecompiledRuntimeConfiguration({this.useElf});
List<Command> computeRuntimeCommands(
CommandArtifact artifact,
@@ -360,7 +360,7 @@
static const deviceTestDir = '/data/local/tmp/precompilation-testing/test';
final bool useElf;
- DartPrecompiledAdbRuntimeConfiguration({bool useElf}) : useElf = useElf;
+ DartPrecompiledAdbRuntimeConfiguration({this.useElf});
List<Command> computeRuntimeCommands(
CommandArtifact artifact,
diff --git a/pkg/test_runner/lib/src/test_progress.dart b/pkg/test_runner/lib/src/test_progress.dart
index 7faf841..850c492 100644
--- a/pkg/test_runner/lib/src/test_progress.dart
+++ b/pkg/test_runner/lib/src/test_progress.dart
@@ -224,12 +224,12 @@
TimingPrinter(this._startTime);
- void done(TestCase testCase) {
- for (var commandOutput in testCase.commandOutputs.values) {
+ void done(TestCase test) {
+ for (var commandOutput in test.commandOutputs.values) {
var command = commandOutput.command;
_commandOutputs.add(commandOutput);
_commandToTestCases.putIfAbsent(command, () => <TestCase>[]);
- _commandToTestCases[command].add(testCase);
+ _commandToTestCases[command].add(test);
}
}
@@ -430,7 +430,7 @@
CompactProgressIndicator(DateTime startTime, this._formatter)
: super(startTime);
- void _printDoneProgress(TestCase testCase) {
+ void _printDoneProgress(TestCase test) {
var percent = ((_completedTests / _foundTests) * 100).toInt().toString();
var progressPadded = (_allTestsKnown ? percent : '--').padLeft(3);
var passedPadded = _passedTests.toString().padLeft(5);
diff --git a/pkg/test_runner/tool/update_static_error_tests.dart b/pkg/test_runner/tool/update_static_error_tests.dart
index 263fc75..eaa1bf8 100644
--- a/pkg/test_runner/tool/update_static_error_tests.dart
+++ b/pkg/test_runner/tool/update_static_error_tests.dart
@@ -8,6 +8,7 @@
import 'package:args/args.dart';
import 'package:glob/glob.dart';
+import 'package:path/path.dart' as p;
import 'package:test_runner/src/command_output.dart';
import 'package:test_runner/src/path.dart';
@@ -18,6 +19,8 @@
const _usage =
"Usage: dart update_static_error_tests.dart [flags...] <path glob>";
+final String _analyzerPath = _findAnalyzer();
+
Future<void> main(List<String> args) async {
var sources = ErrorSource.all.map((e) => e.marker).toList();
@@ -207,15 +210,11 @@
// TODO(rnystrom): Running the analyzer command line each time is very slow.
// Either import the analyzer as a library, or at least invoke it in a batch
// mode.
- var result = await Process.run(
- Platform.isWindows
- ? "sdk\\bin\\dartanalyzer.bat"
- : "sdk/bin/dartanalyzer",
- [
- ...options,
- "--format=machine",
- path,
- ]);
+ var result = await Process.run(_analyzerPath, [
+ ...options,
+ "--format=machine",
+ path,
+ ]);
// Analyzer returns 3 when it detects errors, 2 when it detects
// warnings and --fatal-warnings is enabled, 1 when it detects
@@ -260,3 +259,34 @@
FastaCommandOutput.parseErrors(result.stdout as String, errors);
return errors;
}
+
+/// Find the most recently-built analyzer.
+String _findAnalyzer() {
+ String newestAnalyzer;
+ DateTime newestAnalyzerTime;
+
+ var buildDirectory = Directory(Platform.isMacOS ? "xcodebuild" : "out");
+ if (buildDirectory.existsSync()) {
+ for (var config in buildDirectory.listSync()) {
+ var analyzerPath = p.join(config.path, "dart-sdk", "bin", "dartanalyzer");
+ var analyzerFile = File(analyzerPath);
+ if (!analyzerFile.existsSync()) continue;
+ var modified = analyzerFile.lastModifiedSync();
+
+ if (newestAnalyzerTime == null || modified.isAfter(newestAnalyzerTime)) {
+ newestAnalyzer = analyzerPath;
+ newestAnalyzerTime = modified;
+ }
+ }
+ }
+
+ if (newestAnalyzer == null) {
+ // Clear the current line since we're in the middle of a progress line.
+ print("");
+ print("Could not find a built SDK with a dartanalyzer to run.");
+ print("Make sure to build the Dart SDK before running this tool.");
+ exit(1);
+ }
+
+ return newestAnalyzer;
+}
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 2b47365..c7ebb49 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -268,6 +268,62 @@
const uint8_t* bytes,
intptr_t bytes_length);
+/**
+ * Usage statistics for a space/generation at a particular moment in time.
+ *
+ * \param new_space Data for New Space.
+ *
+ * \param old_space Data for Old Space.
+ */
+typedef struct {
+ /**
+ * \param used_in_words Amount of memory space used, in words.
+ *
+ * \param capacity_in_words Memory space capacity, in words.
+ *
+ * \param external_in_words External memory, in words.
+ */
+ struct {
+ intptr_t used_in_words;
+ intptr_t capacity_in_words;
+ intptr_t external_in_words;
+ } new_space, old_space;
+} Dart_GCStats;
+
+/**
+ * A Garbage Collection event with memory usage statistics.
+ *
+ * \param type The event type. Static lifetime.
+ *
+ * \param reason The reason for the GC event. Static lifetime.
+ *
+ * \param before Memory usage statistics measured before GC was performed.
+ *
+ * \param before Memory usage statistics measured after GC was performed.
+ */
+typedef struct {
+ const char* type;
+ const char* reason;
+ Dart_GCStats before;
+ Dart_GCStats after;
+} Dart_GCEvent;
+
+/**
+ * A callback invoked when the VM emits a GC event.
+ *
+ * \param event The GC event data. Pointer only valid for the duration of the
+ * callback.
+ */
+typedef void (*Dart_GCEventCallback)(Dart_GCEvent* event);
+
+/**
+ * Sets the native GC event callback.
+ *
+ * \param callback A function pointer to an event handler callback function.
+ * A NULL value removes the existing listen callback function if any.
+ */
+DART_EXPORT void Dart_SetGCEventCallback(Dart_GCEventCallback callback);
+
/*
* ========
* Reload support
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e2840ba..1440eaa 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6379,6 +6379,10 @@
return Api::Success();
}
+DART_EXPORT void Dart_SetGCEventCallback(Dart_GCEventCallback callback) {
+ Isolate::Current()->heap()->SetGCEventCallback(callback);
+}
+
DART_EXPORT char* Dart_SetFileModifiedCallback(
Dart_FileModifiedCallback file_modified_callback) {
#if !defined(PRODUCT)
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 25a24ce..51031cc 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -67,7 +67,8 @@
read_only_(false),
last_gc_was_old_space_(false),
assume_scavenge_will_fail_(false),
- gc_on_nth_allocation_(kNoForcedGarbageCollection) {
+ gc_on_nth_allocation_(kNoForcedGarbageCollection),
+ gc_event_callback_(nullptr) {
UpdateGlobalMaxUsed();
for (int sel = 0; sel < kNumWeakSelectors; sel++) {
new_weak_tables_[sel] = new WeakTable();
@@ -1017,6 +1018,35 @@
});
}
#endif // !PRODUCT
+ if (gc_event_callback_ != nullptr) {
+ Dart_GCEvent event;
+
+ event.type = GCTypeToString(stats_.type_);
+ event.reason = GCReasonToString(stats_.reason_);
+
+ event.before.new_space.capacity_in_words =
+ stats_.before_.new_.capacity_in_words;
+ event.before.new_space.external_in_words =
+ stats_.before_.new_.external_in_words;
+ event.before.new_space.used_in_words = stats_.before_.new_.used_in_words;
+ event.before.old_space.capacity_in_words =
+ stats_.before_.old_.capacity_in_words;
+ event.before.old_space.external_in_words =
+ stats_.before_.old_.external_in_words;
+ event.before.old_space.used_in_words = stats_.before_.old_.used_in_words;
+ event.after.new_space.capacity_in_words =
+ stats_.after_.new_.capacity_in_words;
+ event.after.new_space.external_in_words =
+ stats_.after_.new_.external_in_words;
+ event.after.new_space.used_in_words = stats_.after_.new_.used_in_words;
+ event.after.old_space.capacity_in_words =
+ stats_.after_.old_.capacity_in_words;
+ event.after.old_space.external_in_words =
+ stats_.after_.old_.external_in_words;
+ event.after.old_space.used_in_words = stats_.after_.old_.used_in_words;
+
+ (*gc_event_callback_)(&event);
+ }
}
void Heap::PrintStats() {
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 8982ba3..0ea8e09 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -9,6 +9,8 @@
#error "Should not include runtime"
#endif
+#include "include/dart_tools_api.h"
+
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/flags.h"
@@ -320,6 +322,10 @@
void MergeFrom(Heap* donor);
+ void SetGCEventCallback(Dart_GCEventCallback callback) {
+ gc_event_callback_ = callback;
+ }
+
private:
class GCStats : public ValueObject {
public:
@@ -416,6 +422,8 @@
// sensitive codepaths.
intptr_t gc_on_nth_allocation_;
+ Dart_GCEventCallback gc_event_callback_;
+
friend class Become; // VisitObjectPointers
friend class GCCompactor; // VisitObjectPointers
friend class Precompiler; // VisitObjects
@@ -429,6 +437,7 @@
friend class ProgramVisitor; // VisitObjectsImagePages
friend class Serializer; // VisitObjectsImagePages
friend class HeapTestHelper;
+ friend class MetricsTestHelper;
DISALLOW_COPY_AND_ASSIGN(Heap);
};
diff --git a/runtime/vm/metrics_test.cc b/runtime/vm/metrics_test.cc
index 5798b7a..a26aaac 100644
--- a/runtime/vm/metrics_test.cc
+++ b/runtime/vm/metrics_test.cc
@@ -13,6 +13,7 @@
#include "vm/json_stream.h"
#include "vm/metrics.h"
#include "vm/unit_test.h"
+// #include "vm/heap.h"
namespace dart {
@@ -114,4 +115,55 @@
}
}
+class MetricsTestHelper {
+ public:
+ static void Scavenge(Thread* thread) {
+ thread->heap()->CollectNewSpaceGarbage(thread, Heap::kDebugging);
+ }
+};
+
+static uintptr_t event_counter;
+static const char* last_gcevent_type;
+static const char* last_gcevent_reason;
+
+void MyGCEventCallback(Dart_GCEvent* e) {
+ event_counter++;
+ last_gcevent_type = e->type;
+ last_gcevent_reason = e->reason;
+}
+
+ISOLATE_UNIT_TEST_CASE(Metric_SetGCEventCallback) {
+ event_counter = 0;
+ last_gcevent_type = nullptr;
+ last_gcevent_reason = nullptr;
+
+ {
+ TransitionVMToNative transition(Thread::Current());
+
+ const char* kScript = "void main() {}";
+ Dart_Handle api_lib = TestCase::LoadTestScript(
+ kScript, /*resolver=*/nullptr, RESOLVED_USER_TEST_URI);
+ EXPECT_VALID(api_lib);
+ }
+
+ EXPECT_EQ(0UL, event_counter);
+ EXPECT_NULLPTR(last_gcevent_type);
+ EXPECT_NULLPTR(last_gcevent_reason);
+
+ Dart_SetGCEventCallback(&MyGCEventCallback);
+
+ MetricsTestHelper::Scavenge(Thread::Current());
+
+ EXPECT_EQ(1UL, event_counter);
+ EXPECT_STREQ("Scavenge", last_gcevent_type);
+ EXPECT_STREQ("debugging", last_gcevent_reason);
+
+ // This call emits 2 or 3 events.
+ Isolate::Current()->heap()->CollectAllGarbage(Heap::kLowMemory);
+
+ EXPECT_GE(event_counter, 3UL);
+ EXPECT_STREQ("MarkCompact", last_gcevent_type);
+ EXPECT_STREQ("low memory", last_gcevent_reason);
+}
+
} // namespace dart
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index f01e495..3cf75d9 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -1988,6 +1988,12 @@
_socket.destroy();
}
+ void destroyFromExternal() {
+ closed = true;
+ _httpClient._connectionClosedNoFurtherClosing(this);
+ _socket.destroy();
+ }
+
void close() {
closed = true;
_httpClient._connectionClosed(this);
@@ -1996,6 +2002,14 @@
.then((_) => _socket.destroy());
}
+ void closeFromExternal() {
+ closed = true;
+ _httpClient._connectionClosedNoFurtherClosing(this);
+ _streamFuture!
+ .timeout(_httpClient.idleTimeout)
+ .then((_) => _socket.destroy());
+ }
+
Future<_HttpClientConnection> createProxyTunnel(
String host,
int port,
@@ -2141,14 +2155,14 @@
}
if (force) {
for (var c in _idle.toList()) {
- c.destroy();
+ c.destroyFromExternal();
}
for (var c in _active.toList()) {
- c.destroy();
+ c.destroyFromExternal();
}
} else {
for (var c in _idle.toList()) {
- c.close();
+ c.closeFromExternal();
}
}
}
@@ -2486,6 +2500,20 @@
}
}
+ // Remove a closed connection and not issue _closeConnections(). If the close
+ // is signaled from user by calling close(), _closeConnections() was called
+ // and prevent further calls.
+ void _connectionClosedNoFurtherClosing(_HttpClientConnection connection) {
+ connection.stopTimer();
+ var connectionTarget = _connectionTargets[connection.key];
+ if (connectionTarget != null) {
+ connectionTarget.connectionClosed(connection);
+ if (connectionTarget.isEmpty) {
+ _connectionTargets.remove(connection.key);
+ }
+ }
+ }
+
void _connectionsChanged() {
if (_closing) {
_closeConnections(_closingForcefully);
diff --git a/sdk/lib/_internal/vm/bin/file_patch.dart b/sdk/lib/_internal/vm/bin/file_patch.dart
index 033abea..b243920 100644
--- a/sdk/lib/_internal/vm/bin/file_patch.dart
+++ b/sdk/lib/_internal/vm/bin/file_patch.dart
@@ -299,6 +299,15 @@
}
}
} else if (event == RawSocketEvent.closed) {
+ // After this point we should not try to do anything with pathId as
+ // the handle it represented is closed and gone now.
+ if (_idMap.containsKey(pathId)) {
+ _idMap.remove(pathId);
+ if (_idMap.isEmpty && _id != null) {
+ _closeWatcher(_id!);
+ _id = null;
+ }
+ }
} else if (event == RawSocketEvent.readClosed) {
// If Directory watcher buffer overflows, it will send an readClosed event.
// Normal closing will cancel stream subscription so that path is
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index c046c23..6c796d4 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -26,8 +26,6 @@
Language/Statements/Assert/*: Skip # Not migrated to NNBD
Language/Statements/Expression_Statements/syntax_t06: Skip # Type aliases are not fully implemented
Language/Types/Type_Aliases/built-in_types_t11: Skip # Triple shift is not implemented yet
-LanguageFeatures/Constant-update-2018/*: Skip # Not migrated to NNBD
-LanguageFeatures/Control-flow-collections/*: Skip # Not migrated to NNBD
LanguageFeatures/Extension-methods/explicit_extension_member_invocation_A15_t09: Skip # Triple shift is not implemented yet
LanguageFeatures/Instantiate-to-bound/*: Skip # Not migrated to NNBD
LanguageFeatures/Instantiate-to-bound/class/*: Skip # Not migrated to NNBD
diff --git a/tests/standalone/io/http_close_stack_overflow_test.dart b/tests/standalone/io/http_close_stack_overflow_test.dart
new file mode 100644
index 0000000..27055f8
--- /dev/null
+++ b/tests/standalone/io/http_close_stack_overflow_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.
+
+import 'dart:io';
+
+// Test that closing a large amount of servers will not lead to a stack
+// overflow.
+Future<void> main() async {
+ final max = 10000;
+ final servers = <ServerSocket>[];
+ for (var i = 0; i < max; i++) {
+ final server = await ServerSocket.bind("localhost", 0);
+ server.listen((Socket socket) {});
+ servers.add(server);
+ }
+ final client = HttpClient();
+ var got = 0;
+ for (var i = 0; i < max; i++) {
+ new Future(() async {
+ try {
+ final request = await client
+ .getUrl(Uri.parse("http://localhost:${servers[i].port}/"));
+ got++;
+ if (got == max) {
+ // Test that no stack overflow happens.
+ client.close(force: true);
+ for (final server in servers) {
+ server.close();
+ }
+ }
+ final response = await request.close();
+ response.drain();
+ } on HttpException catch (_) {}
+ });
+ }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index fd4c088..73137e9 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -5,6 +5,7 @@
# Tests using the multitest feature where failure is expected should *also* be
# listed in tests/lib/analyzer/analyze_tests.status without the "standalone"
# prefix.
+io/http_close_stack_overflow_test: Skip # The test is heavy loaded. Should be used for manual test.
io/http_linklocal_ipv6_test: SkipByDesign # This needs manual test.
io/non_utf8_directory_test: Skip # Issue 33519. Temp files causing bots to go purple.
io/non_utf8_file_test: Skip # Issue 33519. Temp files causing bots to go purple.
diff --git a/tests/standalone_2/io/http_close_stack_overflow_test.dart b/tests/standalone_2/io/http_close_stack_overflow_test.dart
new file mode 100644
index 0000000..27055f8
--- /dev/null
+++ b/tests/standalone_2/io/http_close_stack_overflow_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.
+
+import 'dart:io';
+
+// Test that closing a large amount of servers will not lead to a stack
+// overflow.
+Future<void> main() async {
+ final max = 10000;
+ final servers = <ServerSocket>[];
+ for (var i = 0; i < max; i++) {
+ final server = await ServerSocket.bind("localhost", 0);
+ server.listen((Socket socket) {});
+ servers.add(server);
+ }
+ final client = HttpClient();
+ var got = 0;
+ for (var i = 0; i < max; i++) {
+ new Future(() async {
+ try {
+ final request = await client
+ .getUrl(Uri.parse("http://localhost:${servers[i].port}/"));
+ got++;
+ if (got == max) {
+ // Test that no stack overflow happens.
+ client.close(force: true);
+ for (final server in servers) {
+ server.close();
+ }
+ }
+ final response = await request.close();
+ response.drain();
+ } on HttpException catch (_) {}
+ });
+ }
+}
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index f99d678..257680b 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -5,6 +5,7 @@
# Tests using the multitest feature where failure is expected should *also* be
# listed in tests/lib/analyzer/analyze_tests.status without the "standalone"
# prefix.
+io/http_close_stack_overflow_test: Skip # The test is heavy loaded. Should be used for manual test.
io/http_linklocal_ipv6_test: SkipByDesign # This needs manual test.
io/non_utf8_directory_test: Skip # Issue 33519. Temp files causing bots to go purple.
io/non_utf8_file_test: Skip # Issue 33519. Temp files causing bots to go purple.
diff --git a/tools/VERSION b/tools/VERSION
index 3d7e732..0adee07 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 76
+PRERELEASE 77
PRERELEASE_PATCH 0
\ No newline at end of file