Version 2.15.0-216.0.dev
Merge commit '868b6a898ca96ad9569ecc4b3ca3925441038841' into 'dev'
diff --git a/DEPS b/DEPS
index d2446c0..54d174b 100644
--- a/DEPS
+++ b/DEPS
@@ -603,11 +603,12 @@
"dep_type": "cipd",
},
+ # Update from https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/gn
Var("dart_root") + "/third_party/fuchsia/sdk/linux": {
"packages": [
{
"package": "fuchsia/sdk/gn/linux-amd64",
- "version": "git_revision:e0a61431eb6e28d31d293cbb0c12f6b3a089bba4"
+ "version": "git_revision:190502a955c482431c2edd0525e128423728b662"
}
],
"condition": 'host_os == "linux" and host_cpu == "x64"',
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 2d4f96e..896bede 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -8257,6 +8257,16 @@
if (token.isIdentifier && optional('.', token.next!)) {
prefix = token;
period = token.next!;
+ Token identifier = period.next!;
+ if (identifier.kind == KEYWORD_TOKEN && optional('new', identifier)) {
+ // Treat `new` after `.` is as an identifier so that it can represent an
+ // unnamed constructor. This support is separate from the
+ // constructor-tearoffs feature.
+ rewriter.replaceTokenFollowing(
+ period,
+ new StringToken(TokenType.IDENTIFIER, identifier.lexeme,
+ identifier.charOffset));
+ }
token = period.next!;
}
if (token.isEof) {
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 55ab879..326a8eb 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -95,30 +95,32 @@
Future<void> test_constructor_unnamed() async {
addTestFile('''
/// [new A] 1
+/// [A.new] 2
class A {
A() {}
- A.other() : this(); // 2
+ A.other() : this(); // 3
}
class B extends A {
- B() : super(); // 3
- factory B.other() = A; // 4
+ B() : super(); // 4
+ factory B.other() = A; // 5
}
void f() {
- A(); // 5
- A.new; // 6
+ A(); // 6
+ A.new; // 7
}
''');
await findElementReferences('A() {}', false);
expect(searchElement!.kind, ElementKind.CONSTRUCTOR);
- expect(results, hasLength(6));
+ expect(results, hasLength(7));
assertHasResult(SearchResultKind.REFERENCE, '] 1', 0);
- assertHasResult(SearchResultKind.INVOCATION, '(); // 2', 0);
+ assertHasResult(SearchResultKind.REFERENCE, '.new] 2', 4);
assertHasResult(SearchResultKind.INVOCATION, '(); // 3', 0);
- assertHasResult(SearchResultKind.REFERENCE, '; // 4', 0);
- assertHasResult(SearchResultKind.INVOCATION, '(); // 5', 0);
- assertHasResult(SearchResultKind.REFERENCE, '.new; // 6', 4);
+ assertHasResult(SearchResultKind.INVOCATION, '(); // 4', 0);
+ assertHasResult(SearchResultKind.REFERENCE, '; // 5', 0);
+ assertHasResult(SearchResultKind.INVOCATION, '(); // 6', 0);
+ assertHasResult(SearchResultKind.REFERENCE, '.new; // 7', 4);
}
Future<void> test_constructor_unnamed_potential() async {
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index cd2d918..ae554f5 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -380,14 +380,10 @@
/// Return `true` if the [node] is a (potentially) constant type expression.
bool check(TypeAnnotation? node) {
- if (potentially) {
- if (node is NamedType) {
- var element = node.name.staticElement;
- if (element is TypeParameterElement) {
- var enclosing = element.enclosingElement;
- return enclosing is ClassElement && !enclosing.isMixin;
- }
- }
+ if (potentially &&
+ node is NamedType &&
+ node.name.staticElement is TypeParameterElement) {
+ return true;
}
if (node is NamedType) {
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index 3406875..0608b1f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -1232,12 +1232,11 @@
* This hint is generated anywhere where `@nonVirtual` annotates something
* other than a non-abstract instance member in a class or mixin.
*
- * Parameters:
- * 0: the name of the member
+ * No Parameters.
*/
static const HintCode INVALID_NON_VIRTUAL_ANNOTATION = HintCode(
'INVALID_NON_VIRTUAL_ANNOTATION',
- "The member '{0}' can't be '@nonVirtual' because it isn't a concrete instance member.",
+ "The annotation '@nonVirtual' can only be applied to a concrete instance member.",
correctionMessage: "Try removing @nonVirtual.",
);
@@ -1297,12 +1296,11 @@
* This hint is generated anywhere where `@sealed` annotates something other
* than a class.
*
- * Parameters:
- * 0: the name of the member
+ * No parameters.
*/
static const HintCode INVALID_SEALED_ANNOTATION = HintCode(
'INVALID_SEALED_ANNOTATION',
- "The member '{0}' is annotated with '@sealed' but only classes can be annotated with it.",
+ "The annotation '@sealed' can only be applied to classes.",
correctionMessage: "Remove @sealed.",
);
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index a611f9f..52c0c39 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -595,7 +595,7 @@
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_METHOD,
function,
- [function.name, enclosingClass],
+ [function.name, receiverType],
);
function.staticType = DynamicTypeImpl.instance;
node.staticType = DynamicTypeImpl.instance;
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 3900f37..a8de577 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -201,29 +201,23 @@
if (parent is FieldDeclaration) {
if (parent.isStatic) {
_errorReporter.reportErrorForNode(
- HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
- node,
- [node.element!.name]);
+ HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
}
} else if (parent is MethodDeclaration) {
if (parent.parent is ExtensionDeclaration ||
parent.isStatic ||
parent.isAbstract) {
_errorReporter.reportErrorForNode(
- HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
- node,
- [node.element!.name]);
+ HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
}
} else {
_errorReporter.reportErrorForNode(
- HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
- node,
- [node.element!.name]);
+ HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
}
} else if (element.isSealed == true) {
if (!(parent is ClassDeclaration || parent is ClassTypeAlias)) {
_errorReporter.reportErrorForNode(
- HintCode.INVALID_SEALED_ANNOTATION, node, [node.element!.name]);
+ HintCode.INVALID_SEALED_ANNOTATION, node);
}
} else if (element.isVisibleForTemplate == true ||
element.isVisibleForTesting == true ||
@@ -240,7 +234,7 @@
_errorReporter.reportErrorForNode(
HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION,
node,
- [declaredElement.name]);
+ [declaredElement.name ?? '<unnamed>']);
}
if (parent is TopLevelVariableDeclaration) {
@@ -275,7 +269,8 @@
reportInvalidVisibleForOverriding(declaredElement);
}
- if (Identifier.isPrivateName(declaredElement.name!)) {
+ var name = declaredElement.name;
+ if (name != null && Identifier.isPrivateName(name)) {
reportInvalidAnnotation(declaredElement);
}
}
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index ca0efc9..684e1ac8 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -112,7 +112,7 @@
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
identifier,
- [node.declaredElement!.name, name],
+ [node.declaredElement!.name ?? '<unnamed>', name],
);
}
}
@@ -126,7 +126,7 @@
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
identifier,
- [node.declaredElement!.name, name],
+ [node.declaredElement!.name ?? '<unnamed>', name],
);
}
}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 7f2a709..daa682e 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -129,27 +129,19 @@
if (identifier is SimpleIdentifierImpl) {
var element = _resolveSimpleIdentifier(identifier);
if (element == null) {
- // TODO(brianwilkerson) Report this error?
- // resolver.reportError(
- // CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
- // simpleIdentifier,
- // simpleIdentifier.getName());
- } else {
- if (element.library == null || element.library != _definingLibrary) {
- // TODO(brianwilkerson) Report this error?
- }
- identifier.staticElement = element;
- if (node.newKeyword != null) {
- if (element is ClassElement) {
- var constructor = element.unnamedConstructor;
- if (constructor == null) {
- // TODO(brianwilkerson) Report this error.
- } else {
- identifier.staticElement = constructor;
- }
- } else {
+ return;
+ }
+ identifier.staticElement = element;
+ if (node.newKeyword != null) {
+ if (element is ClassElement) {
+ var constructor = element.unnamedConstructor;
+ if (constructor == null) {
// TODO(brianwilkerson) Report this error.
+ } else {
+ identifier.staticElement = constructor;
}
+ } else {
+ // TODO(brianwilkerson) Report this error.
}
}
} else if (identifier is PrefixedIdentifierImpl) {
@@ -160,7 +152,6 @@
var name = identifier.identifier;
if (prefixElement == null) {
-// resolver.reportError(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
return;
}
@@ -173,11 +164,6 @@
return;
}
- var library = prefixElement.library;
- if (library != _definingLibrary) {
- // TODO(brianwilkerson) Report this error.
- }
-
if (node.newKeyword == null) {
if (prefixElement is ClassElement) {
name.staticElement = prefixElement.getMethod(name.name) ??
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 2efaaa1..6ae58a0 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -385,7 +385,7 @@
reporter.reportErrorForSpan(
AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
k.span,
- [k.value?.toString()]);
+ [k.value.toString()]);
}
}
if (v is YamlScalar) {
@@ -397,7 +397,7 @@
v.span,
[
AnalyzerOptions.errors,
- v.value?.toString(),
+ v.value.toString(),
legalValueString
]);
}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index bee1e35..cf4a160 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -14959,14 +14959,13 @@
var x;
```
INVALID_NON_VIRTUAL_ANNOTATION:
- problemMessage: "The member '{0}' can't be '@nonVirtual' because it isn't a concrete instance member."
+ problemMessage: "The annotation '@nonVirtual' can only be applied to a concrete instance member."
correctionMessage: Try removing @nonVirtual.
comment: |-
This hint is generated anywhere where `@nonVirtual` annotates something
other than a non-abstract instance member in a class or mixin.
- Parameters:
- 0: the name of the member
+ No Parameters.
INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER:
problemMessage: "The member '{0}' is declared non-virtual in '{1}' and can't be overridden in subclasses."
comment: |-
@@ -15070,14 +15069,13 @@
}
```
INVALID_SEALED_ANNOTATION:
- problemMessage: "The member '{0}' is annotated with '@sealed' but only classes can be annotated with it."
+ problemMessage: "The annotation '@sealed' can only be applied to classes."
correctionMessage: Remove @sealed.
comment: |-
This hint is generated anywhere where `@sealed` annotates something other
than a class.
- Parameters:
- 0: the name of the member
+ No parameters.
INVALID_USE_OF_INTERNAL_MEMBER:
problemMessage: "The member '{0}' can only be used within its package."
comment: |-
diff --git a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
index 3f6571e..7fbe061 100644
--- a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
+++ b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
@@ -256,6 +256,14 @@
expect(methodInvocation.argumentList, isNotNull);
}
+ void test_constructor_tearoff_in_comment_reference() {
+ createParser('');
+ var commentReference = parseCommentReference('C.new', 5)!;
+ var identifier = commentReference.identifier as PrefixedIdentifier;
+ expect(identifier.prefix.name, 'C');
+ expect(identifier.identifier.name, 'new');
+ }
+
void test_constructor_tearoff_method_invocation() {
var methodInvocation =
parseExpression('C.new.toString()', featureSet: constructorTearoffs)
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index 8a70510..e356a67 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -118,42 +118,25 @@
''');
}
- test_typeParameter_ofExtension() async {
- await _assertNeverConst(r'''
-extension E<T> on int {
- void foo() {
- T x;
- }
-}
-''');
- }
-
test_typeParameter_ofFunction() async {
- await _assertNeverConst(r'''
+ await _assertPotentiallyConst('''
void foo<T>() {
T x;
}
''');
}
- test_typeParameter_ofMethod() async {
- await _assertNeverConst(r'''
-class A {
- void foo<T>() {
- T x;
+ test_typeParameter_ofFunctionType() async {
+ await _assertPotentiallyConst('''
+class A<U> {
+ const A();
+ void foo() {
+ void Function<X>(X) x;
}
}
''');
}
- test_typeParameter_ofMixin() async {
- await _assertNeverConst(r'''
-mixin M<T> {
- T x;
-}
-''');
- }
-
test_void() async {
await _assertConst(r'''
void x;
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index fea1532..7f61cf5 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -338,6 +338,23 @@
reference, findElement.method('foo'), 'void Function(int)');
}
+ test_extensionMethod_unknown() async {
+ await assertErrorsInCode('''
+extension on double {
+ bar() {
+ foo<int>;
+ }
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 24, 3),
+ error(CompileTimeErrorCode.UNDEFINED_METHOD, 36, 3,
+ messageContains: "for the type 'double'"),
+ ]);
+
+ assertFunctionReference(
+ findNode.functionReference('foo<int>;'), null, 'dynamic');
+ }
+
test_function_call() async {
await assertNoErrorsInCode('''
void foo<T>(T a) {}
@@ -874,7 +891,8 @@
}
}
''', [
- error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3),
+ error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3,
+ messageContains: "for the type 'A'"),
]);
assertFunctionReference(
diff --git a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
index d2581f7..b85b744 100644
--- a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
@@ -86,6 +86,19 @@
]);
}
+ test_field_getter_unnamed() async {
+ await assertErrorsInCode('''
+extension on String {
+ static int foo = 0;
+ int get foo => 0;
+}
+''', [
+ error(HintCode.UNUSED_FIELD, 35, 3),
+ error(_errorCode, 35, 3, messageContains: "Extension '<unnamed>'"),
+ error(HintCode.UNUSED_ELEMENT, 54, 3),
+ ]);
+ }
+
test_field_method() async {
await assertErrorsInCode('''
extension E on String {
@@ -93,7 +106,7 @@
void foo() {}
}
''', [
- error(_errorCode, 37, 3),
+ error(_errorCode, 37, 3, messageContains: "Extension 'E'"),
]);
}
@@ -115,7 +128,20 @@
int get foo => 0;
}
''', [
- error(_errorCode, 41, 3),
+ error(_errorCode, 41, 3, messageContains: "Extension 'E'"),
+ ]);
+ }
+
+ test_getter_getter_unnamed() async {
+ await assertErrorsInCode('''
+extension on String {
+ static int get foo => 0;
+ int get foo => 0;
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 39, 3),
+ error(_errorCode, 39, 3, messageContains: "Extension '<unnamed>'"),
+ error(HintCode.UNUSED_ELEMENT, 59, 3),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
index 910acf3..9fa9832 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
@@ -27,7 +27,10 @@
import 'package:meta/meta.dart';
@visibleForOverriding
class C {}
-''', [error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21)]);
+''', [
+ error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
+ messageContains: "The declaration 'C'")
+ ]);
}
test_invalid_constructor() async {
@@ -42,6 +45,17 @@
]);
}
+ test_invalid_extension_unnamed() async {
+ await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+@visibleForOverriding
+extension on double {}
+''', [
+ error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
+ messageContains: "The declaration '<unnamed>'")
+ ]);
+ }
+
test_invalid_extensionMember() async {
await assertErrorsInCode(r'''
import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 1deba37c..fe27110 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -333,19 +333,43 @@
}
test_analyzer_error_code_supported_bad_value() {
- validate('''
+ var errors = validate('''
analyzer:
errors:
unused_local_variable: ftw
''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+ expect(errors.single.problemMessage.messageText(includeUrl: false),
+ contains("The option 'ftw'"));
+ }
+
+ test_analyzer_error_code_supported_bad_value_null() {
+ var errors = validate('''
+analyzer:
+ errors:
+ unused_local_variable: null
+ ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+ expect(errors.single.problemMessage.messageText(includeUrl: false),
+ contains("The option 'null'"));
}
test_analyzer_error_code_unsupported() {
- validate('''
+ var errors = validate('''
analyzer:
errors:
not_supported: ignore
''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+ expect(errors.single.problemMessage.messageText(includeUrl: false),
+ contains("'not_supported' isn't a recognized error code"));
+ }
+
+ test_analyzer_error_code_unsupported_null() {
+ var errors = validate('''
+analyzer:
+ errors:
+ null: ignore
+ ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+ expect(errors.single.problemMessage.messageText(includeUrl: false),
+ contains("'null' isn't a recognized error code"));
}
test_analyzer_errors_notAMap() {
@@ -521,11 +545,12 @@
''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
}
- void validate(String source, List<ErrorCode> expected) {
+ List<AnalysisError> validate(String source, List<ErrorCode> expected) {
var options = optionsProvider.getOptionsFromString(source);
var errors = validator.validate(options);
expect(errors.map((AnalysisError e) => e.errorCode),
unorderedEquals(expected));
+ return errors;
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 82d3011..452d6e7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -836,6 +836,16 @@
// The initializer was already compiled (e.g., if it appear in the
// outline, like constant field initializers) so we do not need to
// perform type inference or transformations.
+
+ // If the body is already built and it's a type aliased constructor or
+ // factory invocation, they shouldn't be checked or resolved the
+ // second time, so they are removed from the corresponding lists.
+ if (initializer is TypeAliasedConstructorInvocation) {
+ typeAliasedConstructorInvocations.remove(initializer);
+ }
+ if (initializer is TypeAliasedFactoryInvocation) {
+ typeAliasedFactoryInvocations.remove(initializer);
+ }
} else {
initializer = typeInferrer.inferFieldInitializer(
this, fieldBuilder.builtType, initializer);
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart b/pkg/front_end/parser_testcases/general/new_as_identifier.dart
index 32a868f..30b926d 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart
@@ -7,6 +7,7 @@
//
// Unless otherwise noted, these tests cases should not result in a parse error.
+/// See [C.new].
class C {
C.new();
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
index e3d208d..89b9611 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
@@ -1,42 +1,42 @@
Problems reported:
-parser/general/new_as_identifier:15:44: Expected an identifier, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected an identifier, but got 'new'.
C.constructor_field_initializer() : this.new = null;
^^^
-parser/general/new_as_identifier:15:39: Expected an assignment after the field name.
+parser/general/new_as_identifier:16:39: Expected an assignment after the field name.
C.constructor_field_initializer() : this.new = null;
^^^^
-parser/general/new_as_identifier:15:44: Expected a function body, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected a function body, but got 'new'.
C.constructor_field_initializer() : this.new = null;
^^^
-parser/general/new_as_identifier:15:44: Expected a class member, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected a class member, but got 'new'.
C.constructor_field_initializer() : this.new = null;
^^^
-parser/general/new_as_identifier:15:48: Operator declarations must be preceded by the keyword 'operator'.
+parser/general/new_as_identifier:16:48: Operator declarations must be preceded by the keyword 'operator'.
C.constructor_field_initializer() : this.new = null;
^
-parser/general/new_as_identifier:15:48: The string '=' isn't a user-definable operator.
+parser/general/new_as_identifier:16:48: The string '=' isn't a user-definable operator.
C.constructor_field_initializer() : this.new = null;
^
-parser/general/new_as_identifier:15:48: A method declaration needs an explicit list of parameters.
+parser/general/new_as_identifier:16:48: A method declaration needs an explicit list of parameters.
C.constructor_field_initializer() : this.new = null;
^
-parser/general/new_as_identifier:15:50: Expected a function body, but got 'null'.
+parser/general/new_as_identifier:16:50: Expected a function body, but got 'null'.
C.constructor_field_initializer() : this.new = null;
^^^^
-parser/general/new_as_identifier:15:50: Expected a class member, but got 'null'.
+parser/general/new_as_identifier:16:50: Expected a class member, but got 'null'.
C.constructor_field_initializer() : this.new = null;
^^^^
-parser/general/new_as_identifier:15:54: Expected a class member, but got ';'.
+parser/general/new_as_identifier:16:54: Expected a class member, but got ';'.
C.constructor_field_initializer() : this.new = null;
^
diff --git a/pkg/front_end/testcases/general/issue47339.dart b/pkg/front_end/testcases/general/issue47339.dart
new file mode 100644
index 0000000..0637fa2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+ const Foo.named();
+ const factory Foo.namedFactory() = Foo.named;
+}
+
+typedef Bar = Foo;
+
+const Bar bar = Bar.named();
+
+const Bar bar2 = Bar.namedFactory();
+
+class FooGeneric<X> {
+ const FooGeneric.named();
+ const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+typedef BarGeneric<X> = FooGeneric<X>;
+
+const BarGeneric<int> barGeneric = BarGeneric.named();
+
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect
new file mode 100644
index 0000000..5f8c270
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Foo {
+ const Foo.named();
+ const factory Foo.namedFactory() = Foo.named;
+}
+
+typedef Bar = Foo;
+const Bar bar = Bar.named();
+const Bar bar2 = Bar.namedFactory();
+
+class FooGeneric<X> {
+ const FooGeneric.named();
+ const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+typedef BarGeneric<X> = FooGeneric<X>;
+const BarGeneric<int> barGeneric = BarGeneric.named();
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb8bacb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Foo {
+ const Foo.named();
+ const factory Foo.namedFactory() = Foo.named;
+}
+
+class FooGeneric<X> {
+ const FooGeneric.named();
+ const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+const Bar bar = Bar.named();
+const Bar bar2 = Bar.namedFactory();
+const BarGeneric<int> barGeneric = BarGeneric.named();
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+main() {}
+typedef Bar = Foo;
+typedef BarGeneric<X> = FooGeneric<X>;
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.expect
new file mode 100644
index 0000000..eb5e9b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+ const constructor named() → self::Foo
+ : super core::Object::•()
+ ;
+ static factory namedFactory() → self::Foo
+ return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+ const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+ : super core::Object::•()
+ ;
+ static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+ return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = #C1;
+static const field self::Foo bar2 = #C1;
+static const field self::FooGeneric<core::int> barGeneric = #C2;
+static const field self::FooGeneric<core::int> barGeneric2 = #C2;
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Foo {}
+ #C2 = self::FooGeneric<core::int*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47339.dart:
+- Foo.named (from org-dartlang-testcase:///issue47339.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- FooGeneric.named (from org-dartlang-testcase:///issue47339.dart:17:9)
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect
new file mode 100644
index 0000000..0a83431
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+ const constructor named() → self::Foo
+ : super core::Object::•()
+ ;
+ static factory namedFactory() → self::Foo
+ return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+ const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+ : super core::Object::•()
+ ;
+ static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+ return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = const self::Foo::named();
+static const field self::Foo bar2 = const self::Foo::named();
+static const field self::FooGeneric<core::int> barGeneric = const self::FooGeneric::named<core::int>();
+static const field self::FooGeneric<core::int> barGeneric2 = const self::FooGeneric::named<core::int>();
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:12:11 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:14:22 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:23:23 -> InstanceConstant(const FooGeneric<int*>{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:25:48 -> InstanceConstant(const FooGeneric<int*>{})
+Extra constant evaluation: evaluated: 10, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect
new file mode 100644
index 0000000..eb5e9b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+ const constructor named() → self::Foo
+ : super core::Object::•()
+ ;
+ static factory namedFactory() → self::Foo
+ return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/ {
+ static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+ const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+ : super core::Object::•()
+ ;
+ static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+ return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = #C1;
+static const field self::Foo bar2 = #C1;
+static const field self::FooGeneric<core::int> barGeneric = #C2;
+static const field self::FooGeneric<core::int> barGeneric2 = #C2;
+static method main() → dynamic {}
+
+constants {
+ #C1 = self::Foo {}
+ #C2 = self::FooGeneric<core::int*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47339.dart:
+- Foo.named (from org-dartlang-testcase:///issue47339.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- FooGeneric.named (from org-dartlang-testcase:///issue47339.dart:17:9)
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index b8e3e6c..5b236c2 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -103,6 +103,18 @@
} while (size > 0);
}
+DART_FORCE_INLINE
+static uword ReadHeaderRelaxed(ObjectPtr raw_obj) {
+ return reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
+ ->load(std::memory_order_relaxed);
+}
+
+DART_FORCE_INLINE
+static void WriteHeaderRelaxed(ObjectPtr raw_obj, uword header) {
+ reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
+ ->store(header, std::memory_order_relaxed);
+}
+
template <bool parallel>
class ScavengerVisitorBase : public ObjectPointerVisitor {
public:
@@ -154,16 +166,14 @@
}
// Validate 'this' is a typed data view.
- const uword view_header =
- *reinterpret_cast<uword*>(UntaggedObject::ToAddr(view));
+ const uword view_header = ReadHeaderRelaxed(view);
ASSERT(!IsForwarding(view_header) || view->IsOldObject());
ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
// Validate that the backing store is not a forwarding word.
TypedDataBasePtr td = view->untag()->typed_data();
ASSERT(td->IsHeapObject());
- const uword td_header =
- *reinterpret_cast<uword*>(UntaggedObject::ToAddr(td));
+ const uword td_header = ReadHeaderRelaxed(td);
ASSERT(!IsForwarding(td_header) || td->IsOldObject());
if (!parallel) {
@@ -356,8 +366,7 @@
ASSERT(from_->Contains(raw_addr));
// Read the header word of the object and determine if the object has
// already been copied.
- uword header = reinterpret_cast<std::atomic<uword>*>(raw_addr)->load(
- std::memory_order_relaxed);
+ uword header = ReadHeaderRelaxed(raw_obj);
ObjectPtr new_obj;
if (IsForwarding(header)) {
// Get the new location of the object.
@@ -1306,7 +1315,7 @@
ASSERT(raw_key->IsNewObject());
uword raw_addr = UntaggedObject::ToAddr(raw_key);
ASSERT(from_->Contains(raw_addr));
- uword header = *reinterpret_cast<uword*>(raw_addr);
+ uword header = ReadHeaderRelaxed(raw_key);
// Reset the next pointer in the weak property.
cur_weak->untag()->next_ = WeakProperty::null();
if (IsForwarding(header)) {
@@ -1351,8 +1360,7 @@
ASSERT(raw_weak->IsNewObject());
ASSERT(raw_weak->IsWeakProperty());
#if defined(DEBUG)
- uword raw_addr = UntaggedObject::ToAddr(raw_weak);
- uword header = *reinterpret_cast<uword*>(raw_addr);
+ uword header = ReadHeaderRelaxed(raw_weak);
ASSERT(!IsForwarding(header));
#endif // defined(DEBUG)
ASSERT(raw_weak->untag()->next_ ==
@@ -1369,8 +1377,7 @@
// The fate of the weak property is determined by its key.
ObjectPtr raw_key = raw_weak->untag()->key();
if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
- uword raw_addr = UntaggedObject::ToAddr(raw_key);
- uword header = *reinterpret_cast<uword*>(raw_addr);
+ uword header = ReadHeaderRelaxed(raw_key);
if (!IsForwarding(header)) {
// Key is white. Enqueue the weak property.
EnqueueWeakProperty(raw_weak);
@@ -1714,20 +1721,11 @@
TIMELINE_FUNCTION_GC_DURATION(thread, "ReverseScavenge");
class ReverseFromForwardingVisitor : public ObjectVisitor {
- uword ReadHeader(ObjectPtr raw_obj) {
- return reinterpret_cast<std::atomic<uword>*>(
- UntaggedObject::ToAddr(raw_obj))
- ->load(std::memory_order_relaxed);
- }
- void WriteHeader(ObjectPtr raw_obj, uword header) {
- reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
- ->store(header, std::memory_order_relaxed);
- }
void VisitObject(ObjectPtr from_obj) {
- uword from_header = ReadHeader(from_obj);
+ uword from_header = ReadHeaderRelaxed(from_obj);
if (IsForwarding(from_header)) {
ObjectPtr to_obj = ForwardedObj(from_header);
- uword to_header = ReadHeader(to_obj);
+ uword to_header = ReadHeaderRelaxed(to_obj);
intptr_t size = to_obj->untag()->HeapSize();
// Reset the ages bits in case this was a promotion.
@@ -1739,7 +1737,7 @@
from_header =
UntaggedObject::OldAndNotMarkedBit::update(false, from_header);
- WriteHeader(from_obj, from_header);
+ WriteHeaderRelaxed(from_obj, from_header);
ForwardingCorpse::AsForwarder(UntaggedObject::ToAddr(to_obj), size)
->set_target(from_obj);
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index 737f28c..3f740d5 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -77,9 +77,9 @@
/// ```
///
/// ```dart
- /// DynamicLibrary dylib;
- /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32),
- /// int Function(int, int)>('add');
+ /// DynamicLibrary dylib = DynamicLibrary.executable();
+ /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32), int Function(int, int)>(
+ /// 'add');
/// ```
external F lookupFunction<T extends Function, F extends Function>(
String symbolName,
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index bffde99..f8283f9 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -7,6 +7,10 @@
/// but don't share memory,
/// communicating only via messages.
///
+/// *NOTE*: The `dart:isolate` library is currently only supported by the
+/// [Dart Native](https://dart.dev/overview#platform) platform.
+
+///
/// To use this library in your code:
/// ```dart
/// import 'dart:isolate';
@@ -608,9 +612,7 @@
/// In the special circumstances when two isolates share the same code and are
/// running in the same process (e.g. isolates created via [Isolate.spawn]),
/// it is also possible to send object instances (which would be copied in the
- /// process). This is currently only supported by the
- /// [Dart Native](https://dart.dev/platforms#dart-native-vm-jit-and-aot)
- /// platform.
+ /// process).
///
/// The send happens immediately and doesn't block. The corresponding receive
/// port can receive the message as soon as its isolate's event loop is ready
diff --git a/tools/VERSION b/tools/VERSION
index 1328561..d6d0abc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 215
+PRERELEASE 216
PRERELEASE_PATCH 0
\ No newline at end of file