Version 2.15.0-273.0.dev
Merge commit '7913e0fe1688030649fd1f2fbd7f711456156cbe' into 'dev'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
index 5cb45e5..65b56f4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
@@ -363,7 +363,7 @@
}
''',
errorFilter: (AnalysisError error) =>
- error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+ error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
}
Future<void> test_yieldEach_localFunction() async {
@@ -402,7 +402,7 @@
}
''',
errorFilter: (AnalysisError error) =>
- error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+ error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
}
Future<void> test_yieldEach_topLevel() async {
@@ -417,6 +417,6 @@
}
''',
errorFilter: (AnalysisError error) =>
- error.errorCode != CompileTimeErrorCode.YIELD_OF_INVALID_TYPE);
+ error.errorCode != CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE);
}
}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 1c98a3a..6e3a83b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -475,6 +475,7 @@
CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_POSITION,
CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR,
CompileTimeErrorCode.YIELD_IN_NON_GENERATOR,
+ CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
FfiCode.ANNOTATION_ON_POINTER_FIELD,
FfiCode.ARGUMENT_MUST_BE_A_CONSTANT,
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index ac9fbb1..3e230c6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -643,7 +643,7 @@
TypeAliasElement? viaTypeAlias;
if (typeElement is TypeAliasElementImpl) {
if (constructorFunctionType.typeFormals.isNotEmpty &&
- !typeElement.isProperRename()) {
+ !typeElement.isProperRename) {
// The type alias is not a proper rename of the aliased class, so
// the constructor tear-off is distinct from the associated
// constructor function of the aliased class.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d5bc77f..9b9add9 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5482,6 +5482,34 @@
CompilationUnitElement get enclosingElement =>
super.enclosingElement as CompilationUnitElement;
+ /// Returns whether this alias is a "proper rename" of [aliasedClass], as
+ /// defined in the constructor-tearoffs specification.
+ bool get isProperRename {
+ var aliasedType_ = aliasedType;
+ if (aliasedType_ is! InterfaceType) {
+ return false;
+ }
+ var aliasedClass = aliasedType_.element;
+ var typeArguments = aliasedType_.typeArguments;
+ var typeParameterCount = typeParameters.length;
+ if (typeParameterCount != aliasedClass.typeParameters.length) {
+ return false;
+ }
+ for (var i = 0; i < typeParameterCount; i++) {
+ var bound = typeParameters[i].bound ?? library.typeProvider.dynamicType;
+ var aliasedBound = aliasedClass.typeParameters[i].bound ??
+ library.typeProvider.dynamicType;
+ if (!library.typeSystem.isSubtypeOf(bound, aliasedBound) ||
+ !library.typeSystem.isSubtypeOf(aliasedBound, bound)) {
+ return false;
+ }
+ if (typeParameters[i] != typeArguments[i].element) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@override
ElementKind get kind {
if (isNonFunctionTypeAliasesEnabled) {
@@ -5582,37 +5610,6 @@
}
}
- /// Returns whether this alias is a "proper rename" of [aliasedClass], as
- /// defined in the constructor-tearoffs specification.
- bool isProperRename() {
- var aliasedType_ = aliasedType;
- if (aliasedType_ is! InterfaceType) {
- return false;
- }
- var aliasedClass = aliasedType_.element;
- var typeArguments = aliasedType_.typeArguments;
- var typeParameterCount = typeParameters.length;
- if (typeParameterCount != aliasedClass.typeParameters.length) {
- return false;
- }
- if (typeParameterCount != typeArguments.length) {
- return false;
- }
- for (var i = 0; i < typeParameterCount; i++) {
- var bound = typeParameters[i].bound ?? library.typeProvider.dynamicType;
- var aliasedBound = aliasedClass.typeParameters[i].bound ??
- library.typeProvider.dynamicType;
- if (!library.typeSystem.isSubtypeOf(bound, aliasedBound) ||
- !library.typeSystem.isSubtypeOf(aliasedBound, bound)) {
- return false;
- }
- if (typeParameters[i] != typeArguments[i].element) {
- return false;
- }
- }
- return true;
- }
-
void setLinkedData(Reference reference, ElementLinkedData linkedData) {
this.reference = reference;
reference.element = this;
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 157ba4c..d0f35da 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -240,7 +240,7 @@
node: node,
requested: writeElementRequested,
recovery: writeElementRecovery,
- receiverTypeObject: null,
+ receiverType: null,
);
}
@@ -469,7 +469,7 @@
node: propertyName,
requested: null,
recovery: result.getter,
- receiverTypeObject: targetType,
+ receiverType: targetType,
);
}
}
@@ -543,7 +543,7 @@
node: propertyName,
requested: null,
recovery: writeElementRecovery,
- receiverTypeObject: typeReference.displayName,
+ receiverType: typeReference.thisType,
);
}
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
index 6e47fa5..02e043b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/yield_statement_resolver.dart
@@ -70,9 +70,9 @@
/// This method should only be called in generator functions.
void _checkForYieldOfInvalidType(
BodyInferenceContext bodyContext,
- YieldStatement node,
- bool isYieldEach,
- ) {
+ YieldStatement node, {
+ required bool isYieldEach,
+ }) {
var expression = node.expression;
var expressionType = expression.typeOrThrow;
@@ -88,11 +88,25 @@
var imposedReturnType = bodyContext.imposedType;
if (imposedReturnType != null &&
!_typeSystem.isAssignableTo(impliedReturnType, imposedReturnType)) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
- expression,
- [impliedReturnType, imposedReturnType],
- );
+ if (isYieldEach) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
+ expression,
+ [impliedReturnType, imposedReturnType],
+ );
+ return;
+ }
+ var imposedTypeAsInstanceOf = bodyContext.isSynchronous
+ ? imposedReturnType.asInstanceOf(_typeProvider.iterableElement)
+ : imposedReturnType.asInstanceOf(_typeProvider.streamElement);
+ var imposedValueType = imposedTypeAsInstanceOf?.typeArguments[0];
+ if (imposedValueType != null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
+ expression,
+ [expressionType, imposedValueType],
+ );
+ }
return;
}
@@ -109,7 +123,7 @@
if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) {
_errorReporter.reportErrorForNode(
- CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
+ CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE,
expression,
[impliedReturnType, requiredReturnType],
);
@@ -134,7 +148,8 @@
bodyContext.addYield(node);
- _checkForYieldOfInvalidType(bodyContext, node, node.star != null);
+ _checkForYieldOfInvalidType(bodyContext, node,
+ isYieldEach: node.star != null);
_checkForUseOfVoidResult(node.expression);
}
diff --git a/pkg/analyzer/lib/src/error/assignment_verifier.dart b/pkg/analyzer/lib/src/error/assignment_verifier.dart
index a995629..97cbefd 100644
--- a/pkg/analyzer/lib/src/error/assignment_verifier.dart
+++ b/pkg/analyzer/lib/src/error/assignment_verifier.dart
@@ -25,14 +25,14 @@
/// element, which is definitely not a valid write target. We want to report
/// a good error about this.
///
- /// The [receiverTypeObject] might be a [DartType] or [String], and when
- /// it is not `null`, we report [CompileTimeErrorCode.UNDEFINED_SETTER]
- /// instead of a more generic [CompileTimeErrorCode.UNDEFINED_IDENTIFIER].
+ /// When the [receiverType] is not `null`, we report
+ /// [CompileTimeErrorCode.UNDEFINED_SETTER] instead of a more generic
+ /// [CompileTimeErrorCode.UNDEFINED_IDENTIFIER].
void verify({
required SimpleIdentifier node,
required Element? requested,
required Element? recovery,
- required Object? receiverTypeObject,
+ required DartType? receiverType,
}) {
if (requested != null) {
if (requested is VariableElement) {
@@ -106,11 +106,11 @@
if (node.isSynthetic) {
return;
}
- if (receiverTypeObject != null) {
+ if (receiverType != null) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_SETTER,
node,
- [node.name, receiverTypeObject],
+ [node.name, receiverType],
);
} else {
_errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index cd94929..c9e3ac0 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -15614,6 +15614,19 @@
);
/**
+ * Parameters:
+ * 0: the type of the expression after `yield*`
+ * 1: the return type of the function containing the `yield*`
+ */
+ static const CompileTimeErrorCode YIELD_EACH_OF_INVALID_TYPE =
+ CompileTimeErrorCode(
+ 'YIELD_OF_INVALID_TYPE',
+ "The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'.",
+ hasPublishedDocs: true,
+ uniqueName: 'YIELD_EACH_OF_INVALID_TYPE',
+ );
+
+ /**
* ?? Yield: It is a compile-time error if a yield statement appears in a
* function that is not a generator function.
*
@@ -15635,10 +15648,11 @@
*/
// #### Description
//
- // The analyzer produces this diagnostic when the type of object produced by a
- // `yield` expression doesn't match the type of objects that are to be
- // returned from the `Iterable` or `Stream` types that are returned from a
- // generator (a function or method marked with either `sync*` or `async*`).
+ // The analyzer produces this diagnostic when the type of object produced by
+ // a `yield` or `yield*` expression doesn't match the type of objects that
+ // are to be returned from the `Iterable` or `Stream` types that are returned
+ // from a generator (a function or method marked with either `sync*` or
+ // `async*`).
//
// #### Example
//
@@ -15674,7 +15688,7 @@
static const CompileTimeErrorCode YIELD_OF_INVALID_TYPE =
CompileTimeErrorCode(
'YIELD_OF_INVALID_TYPE',
- "The type '{0}' implied by the 'yield' expression must be assignable to '{1}'.",
+ "A yielded value of type '{0}' must be assignable to '{1}'.",
hasPublishedDocs: true,
);
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 3637c8d..05a30d9 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -13715,8 +13715,16 @@
function that is not a generator function.
No parameters.
+ YIELD_EACH_OF_INVALID_TYPE:
+ sharedName: YIELD_OF_INVALID_TYPE
+ problemMessage: "The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'."
+ hasPublishedDocs: true
+ comment: |-
+ Parameters:
+ 0: the type of the expression after `yield*`
+ 1: the return type of the function containing the `yield*`
YIELD_OF_INVALID_TYPE:
- problemMessage: "The type '{0}' implied by the 'yield' expression must be assignable to '{1}'."
+ problemMessage: "A yielded value of type '{0}' must be assignable to '{1}'."
hasPublishedDocs: true
comment: |-
Parameters:
@@ -13725,10 +13733,11 @@
documentation: |-
#### Description
- The analyzer produces this diagnostic when the type of object produced by a
- `yield` expression doesn't match the type of objects that are to be
- returned from the `Iterable` or `Stream` types that are returned from a
- generator (a function or method marked with either `sync*` or `async*`).
+ The analyzer produces this diagnostic when the type of object produced by
+ a `yield` or `yield*` expression doesn't match the type of objects that
+ are to be returned from the `Iterable` or `Stream` types that are returned
+ from a generator (a function or method marked with either `sync*` or
+ `async*`).
#### Example
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 26f0785..652108c 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -64,6 +64,18 @@
);
}
+ test_identical_constructorReference_aliasIsNotProperRename_differentCount2() async {
+ await resolveTestCode('''
+class C<T, U> {}
+typedef MyC<T> = C;
+const a = identical(MyC.new, C.new);
+''');
+ expect(
+ _evaluateConstant('a'),
+ _boolValue(false),
+ );
+ }
+
test_identical_constructorReference_aliasIsNotProperRename_differentOrder() async {
await resolveTestCode('''
class C<T, U> {}
@@ -124,7 +136,7 @@
);
}
- test_identical_constructorReference_aliasIsProperRename_mutualSubtypes() async {
+ test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_dynamic() async {
await resolveTestCode('''
class C<T> {}
typedef MyC<T extends Object?> = C<T>;
@@ -136,6 +148,18 @@
);
}
+ test_identical_constructorReference_aliasIsProperRename_mutualSubtypes_futureOr() async {
+ await resolveTestCode('''
+class C<T extends num> {}
+typedef MyC<T extends FutureOr<num>> = C<T>;
+const a = identical(MyC<int>.new, MyC<int>.new);
+''');
+ expect(
+ _evaluateConstant('a'),
+ _boolValue(true),
+ );
+ }
+
test_identical_constructorReference_aliasIsProperRename_uninstantiated() async {
await resolveTestCode('''
class C<T> {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index d97a894..a577c7f 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -36,7 +36,8 @@
class T {}
f(T e1) { e1.m = 0; }
''', [
- error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1),
+ error(CompileTimeErrorCode.UNDEFINED_SETTER, 24, 1,
+ messageContains: ["the type 'T'"]),
]);
}
@@ -99,7 +100,8 @@
f(var p) {
f(C.s = 1);
}''', [
- error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1),
+ error(CompileTimeErrorCode.UNDEFINED_SETTER, 75, 1,
+ messageContains: ["type 'C'"]),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 8eec4b2..44ea839 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -1651,7 +1651,7 @@
yield* x;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 37, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 37, 1),
error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE_IN_YIELD_EACH,
37, 1),
]);
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index ddb8c9c..6eda8bd 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -39,7 +39,6 @@
}
''', [
error(CompileTimeErrorCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, 0, 3),
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 25, 1),
]);
}
@@ -58,7 +57,6 @@
}
''', [
error(CompileTimeErrorCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, 0, 13),
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 1),
]);
}
@@ -140,7 +138,6 @@
}
''', [
error(CompileTimeErrorCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, 0, 3),
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 24, 1),
]);
}
@@ -198,7 +195,6 @@
}
''', [
error(CompileTimeErrorCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, 0, 11),
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 32, 1),
]);
}
@@ -246,7 +242,7 @@
yield* 0;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 22, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 22, 1),
]);
}
@@ -257,7 +253,7 @@
yield* a;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 41, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 41, 1),
]);
}
@@ -268,7 +264,7 @@
yield* a;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 53, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 53, 1),
]);
}
@@ -279,7 +275,7 @@
yield* a;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 56, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 56, 1),
]);
}
@@ -303,7 +299,7 @@
Stream g() => throw 0;
''',
expectedErrorsByNullability(nullable: [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 34, 3),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 34, 3),
], legacy: []));
}
@@ -335,7 +331,7 @@
Stream<String> g() => throw 0;
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 34, 3),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 34, 3),
]);
}
@@ -375,7 +371,7 @@
yield* 0;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 21, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 21, 1),
]);
}
@@ -388,7 +384,7 @@
f;
}
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 41, 1),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 41, 1),
]);
}
@@ -412,7 +408,7 @@
Iterable g() => throw 0;
''',
expectedErrorsByNullability(nullable: [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 3),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 35, 3),
], legacy: []));
}
@@ -444,7 +440,7 @@
Iterable<String> g() => throw 0;
''', [
- error(CompileTimeErrorCode.YIELD_OF_INVALID_TYPE, 35, 3),
+ error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 35, 3),
]);
}
}
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 3fdc9d9..942444c 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -15753,14 +15753,17 @@
### yield_of_invalid_type
-_The type '{0}' implied by the 'yield' expression must be assignable to '{1}'._
+_A yielded value of type '{0}' must be assignable to '{1}'._
+
+_The type '{0}' implied by the 'yield*' expression must be assignable to '{1}'._
#### Description
-The analyzer produces this diagnostic when the type of object produced by a
-`yield` expression doesn't match the type of objects that are to be
-returned from the `Iterable` or `Stream` types that are returned from a
-generator (a function or method marked with either `sync*` or `async*`).
+The analyzer produces this diagnostic when the type of object produced by
+a `yield` or `yield*` expression doesn't match the type of objects that
+are to be returned from the `Iterable` or `Stream` types that are returned
+from a generator (a function or method marked with either `sync*` or
+`async*`).
#### Example
diff --git a/pkg/analyzer/tool/messages/error_code_info.dart b/pkg/analyzer/tool/messages/error_code_info.dart
index 907a564..47bb260 100644
--- a/pkg/analyzer/tool/messages/error_code_info.dart
+++ b/pkg/analyzer/tool/messages/error_code_info.dart
@@ -76,7 +76,7 @@
];
/// Decoded messages from the analyzer's `messages.yaml` file.
-final Map<String, Map<String, ErrorCodeInfo>> analyzerMessages =
+final Map<String, Map<String, AnalyzerErrorCodeInfo>> analyzerMessages =
_loadAnalyzerMessages();
/// The path to the `analyzer` package.
@@ -88,7 +88,8 @@
CfeToAnalyzerErrorCodeTables._(frontEndMessages);
/// Decoded messages from the front end's `messages.yaml` file.
-final Map<String, ErrorCodeInfo> frontEndMessages = _loadFrontEndMessages();
+final Map<String, FrontEndErrorCodeInfo> frontEndMessages =
+ _loadFrontEndMessages();
/// The path to the `front_end` package.
final String frontEndPkgPath =
@@ -110,13 +111,13 @@
/// Decodes a YAML object (obtained from `pkg/analyzer/messages.yaml`) into a
/// two-level map of [ErrorCodeInfo], indexed first by class name and then by
/// error name.
-Map<String, Map<String, ErrorCodeInfo>> decodeAnalyzerMessagesYaml(
+Map<String, Map<String, AnalyzerErrorCodeInfo>> decodeAnalyzerMessagesYaml(
Object? yaml) {
Never problem(String message) {
throw 'Problem in pkg/analyzer/messages.yaml: $message';
}
- var result = <String, Map<String, ErrorCodeInfo>>{};
+ var result = <String, Map<String, AnalyzerErrorCodeInfo>>{};
if (yaml is! Map<Object?, Object?>) {
problem('root node is not a map');
}
@@ -142,7 +143,7 @@
}
try {
(result[className] ??= {})[errorName] =
- ErrorCodeInfo.fromYaml(errorValue);
+ AnalyzerErrorCodeInfo.fromYaml(errorValue);
} catch (e) {
problem('while processing '
'$className.$errorName, $e');
@@ -154,12 +155,12 @@
/// Decodes a YAML object (obtained from `pkg/front_end/messages.yaml`) into a
/// map from error name to [ErrorCodeInfo].
-Map<String, ErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
+Map<String, FrontEndErrorCodeInfo> decodeCfeMessagesYaml(Object? yaml) {
Never problem(String message) {
throw 'Problem in pkg/front_end/messages.yaml: $message';
}
- var result = <String, ErrorCodeInfo>{};
+ var result = <String, FrontEndErrorCodeInfo>{};
if (yaml is! Map<Object?, Object?>) {
problem('root node is not a map');
}
@@ -172,25 +173,49 @@
if (errorValue is! Map<Object?, Object?>) {
problem('value associated with error $errorName is not a map');
}
- result[errorName] = ErrorCodeInfo.fromYaml(errorValue);
+ result[errorName] = FrontEndErrorCodeInfo.fromYaml(errorValue);
}
return result;
}
/// Loads analyzer messages from the analyzer's `messages.yaml` file.
-Map<String, Map<String, ErrorCodeInfo>> _loadAnalyzerMessages() {
+Map<String, Map<String, AnalyzerErrorCodeInfo>> _loadAnalyzerMessages() {
Object? messagesYaml =
loadYaml(File(join(analyzerPkgPath, 'messages.yaml')).readAsStringSync());
return decodeAnalyzerMessagesYaml(messagesYaml);
}
/// Loads front end messages from the front end's `messages.yaml` file.
-Map<String, ErrorCodeInfo> _loadFrontEndMessages() {
+Map<String, FrontEndErrorCodeInfo> _loadFrontEndMessages() {
Object? messagesYaml =
loadYaml(File(join(frontEndPkgPath, 'messages.yaml')).readAsStringSync());
return decodeCfeMessagesYaml(messagesYaml);
}
+/// In-memory representation of error code information obtained from the
+/// analyzer's `messages.yaml` file.
+class AnalyzerErrorCodeInfo extends ErrorCodeInfo {
+ AnalyzerErrorCodeInfo(
+ {String? comment,
+ String? correctionMessage,
+ String? documentation,
+ bool hasPublishedDocs = false,
+ bool isUnresolvedIdentifier = false,
+ required String problemMessage,
+ String? sharedName})
+ : super(
+ comment: comment,
+ correctionMessage: correctionMessage,
+ documentation: documentation,
+ hasPublishedDocs: hasPublishedDocs,
+ isUnresolvedIdentifier: isUnresolvedIdentifier,
+ problemMessage: problemMessage,
+ sharedName: sharedName);
+
+ AnalyzerErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
+ : super.fromYaml(yaml);
+}
+
/// Data tables mapping between CFE errors and their corresponding automatically
/// generated analyzer errors.
class CfeToAnalyzerErrorCodeTables {
@@ -218,7 +243,7 @@
/// automatically generated, and whose values are the front end error name.
final Map<ErrorCodeInfo, String> infoToFrontEndCode = {};
- CfeToAnalyzerErrorCodeTables._(Map<String, ErrorCodeInfo> messages) {
+ CfeToAnalyzerErrorCodeTables._(Map<String, FrontEndErrorCodeInfo> messages) {
for (var entry in messages.entries) {
var errorCodeInfo = entry.value;
var index = errorCodeInfo.index;
@@ -322,14 +347,10 @@
String get typeCode => 'ErrorType.$type';
}
-/// In-memory representation of error code information obtained from either a
-/// `messages.yaml` file. Supports both the analyzer and front_end message file
-/// formats.
-class ErrorCodeInfo {
- /// For error code information obtained from the CFE, the set of analyzer
- /// error codes that corresponds to this error code, if any.
- final List<String> analyzerCode;
-
+/// In-memory representation of error code information obtained from either the
+/// analyzer or the front end's `messages.yaml` file. This class contains the
+/// common functionality supported by both formats.
+abstract class ErrorCodeInfo {
/// If present, a documentation comment that should be associated with the
/// error in code generated output.
final String? comment;
@@ -345,10 +366,6 @@
/// been published.
final bool hasPublishedDocs;
- /// For error code information obtained from the CFE, the index of the error
- /// in the analyzer's `fastaAnalyzerErrorCodes` table.
- final int? index;
-
/// Indicates whether this error is caused by an unresolved identifier.
final bool isUnresolvedIdentifier;
@@ -361,11 +378,9 @@
final String? sharedName;
ErrorCodeInfo(
- {this.analyzerCode = const [],
- this.comment,
+ {this.comment,
this.documentation,
this.hasPublishedDocs = false,
- this.index,
this.isUnresolvedIdentifier = false,
this.sharedName,
required this.problemMessage,
@@ -374,12 +389,10 @@
/// Decodes an [ErrorCodeInfo] object from its YAML representation.
ErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
: this(
- analyzerCode: _decodeAnalyzerCode(yaml['analyzerCode']),
comment: yaml['comment'] as String?,
correctionMessage: yaml['correctionMessage'] as String?,
documentation: yaml['documentation'] as String?,
hasPublishedDocs: yaml['hasPublishedDocs'] as bool? ?? false,
- index: yaml['index'] as int?,
isUnresolvedIdentifier:
yaml['isUnresolvedIdentifier'] as bool? ?? false,
problemMessage: yaml['problemMessage'] as String,
@@ -459,8 +472,6 @@
/// Encodes this object into a YAML representation.
Map<Object?, Object?> toYaml() => {
if (sharedName != null) 'sharedName': sharedName,
- if (analyzerCode.isNotEmpty)
- 'analyzerCode': _encodeAnalyzerCode(analyzerCode),
'problemMessage': problemMessage,
if (correctionMessage != null) 'correctionMessage': correctionMessage,
if (isUnresolvedIdentifier) 'isUnresolvedIdentifier': true,
@@ -468,6 +479,30 @@
if (comment != null) 'comment': comment,
if (documentation != null) 'documentation': documentation,
};
+}
+
+/// In-memory representation of error code information obtained from the front
+/// end's `messages.yaml` file.
+class FrontEndErrorCodeInfo extends ErrorCodeInfo {
+ /// The set of analyzer error codes that corresponds to this error code, if
+ /// any.
+ final List<String> analyzerCode;
+
+ /// The index of the error in the analyzer's `fastaAnalyzerErrorCodes` table.
+ final int? index;
+
+ FrontEndErrorCodeInfo.fromYaml(Map<Object?, Object?> yaml)
+ : analyzerCode = _decodeAnalyzerCode(yaml['analyzerCode']),
+ index = yaml['index'] as int?,
+ super.fromYaml(yaml);
+
+ @override
+ Map<Object?, Object?> toYaml() => {
+ if (analyzerCode.isNotEmpty)
+ 'analyzerCode': _encodeAnalyzerCode(analyzerCode),
+ if (index != null) 'index': index,
+ ...super.toYaml(),
+ };
static List<String> _decodeAnalyzerCode(Object? value) {
if (value == null) {
diff --git a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
index 75b6f60..d26eab1 100644
--- a/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
+++ b/pkg/analyzer/tool/messages/extract_errors_to_yaml.dart
@@ -221,7 +221,7 @@
var commentInfo = _extractCommentInfo(fieldDeclaration);
var documentationComment = commentInfo.documentationComment;
var otherComment = commentInfo.otherComment;
- yamlCodes[uniqueNameSuffix] = ErrorCodeInfo(
+ yamlCodes[uniqueNameSuffix] = AnalyzerErrorCodeInfo(
sharedName: uniqueNameSuffix == name ? null : name,
problemMessage: code.problemMessage,
correctionMessage: code.correctionMessage,
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index bb24d00..6cb8860 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -896,7 +896,7 @@
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
const char* prefixed_name = PrefixLongFilePath(name);
- File::Type type = GetType(namespc, prefixed_name, false);
+ File::Type type = GetType(namespc, prefixed_name, true);
data[kType] = type;
if (type != kDoesNotExist) {
struct _stat64 st;
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index df755a73..00cf482 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -879,7 +879,6 @@
if (IsSnapshottingForPrecompilation()) {
vm_options.AddArgument("--precompilation");
} else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
- vm_options.AddArgument("--fields_may_be_reset");
#if !defined(TARGET_ARCH_IA32)
vm_options.AddArgument("--link_natives_lazily");
#endif
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 4193965..8227e2b7 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1213,9 +1213,6 @@
try_load_snapshots_lambda();
}
- if (Options::gen_snapshot_kind() == kAppJIT) {
- vm_options.AddArgument("--fields_may_be_reset");
- }
#if defined(DART_PRECOMPILED_RUNTIME)
vm_options.AddArgument("--precompilation");
#endif
diff --git a/runtime/tests/concurrency/stress_test_list.json b/runtime/tests/concurrency/stress_test_list.json
index f851825..067339d 100644
--- a/runtime/tests/concurrency/stress_test_list.json
+++ b/runtime/tests/concurrency/stress_test_list.json
@@ -3230,7 +3230,6 @@
"../../../tests/standalone/double_smi_comparison_test.dart",
"../../../tests/standalone/double_temp_test.dart",
"../../../tests/standalone/double_to_int_test.dart",
- "../../../tests/standalone/fields_may_be_reset_test.dart",
"../../../tests/standalone/float_array_test.dart",
"../../../tests/standalone/fragmentation_typed_data_test.dart",
"../../../tests/standalone/int_array_load_elimination_test.dart",
@@ -6560,7 +6559,6 @@
"../../../tests/standalone_2/double_smi_comparison_test.dart",
"../../../tests/standalone_2/double_temp_test.dart",
"../../../tests/standalone_2/double_to_int_test.dart",
- "../../../tests/standalone_2/fields_may_be_reset_test.dart",
"../../../tests/standalone_2/float_array_test.dart",
"../../../tests/standalone_2/int_array_load_elimination_test.dart",
"../../../tests/standalone_2/int_array_test.dart",
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 50418b8..f4f5424 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -845,17 +845,9 @@
}
void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) {
- if (!FLAG_fields_may_be_reset) {
- const Field& field = instr->field();
- ASSERT(field.is_static());
- auto& obj = Object::Handle(Z);
- if (field.is_final() && instr->IsFieldInitialized(&obj)) {
- if (obj.IsSmi() || (obj.IsOld() && obj.IsCanonical())) {
- SetValue(instr, obj);
- return;
- }
- }
- }
+ // Cannot treat an initialized field as constant because the same code will be
+ // used when the AppAOT or AppJIT starts over with everything uninitialized or
+ // another isolate in the isolate group starts with everything uninitialized.
SetValue(instr, non_constant_);
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 8e7e24d..d4276ad 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1077,45 +1077,6 @@
return field().ptr() == other.AsLoadStaticField()->field().ptr();
}
-bool LoadStaticFieldInstr::IsFieldInitialized(Object* field_value) const {
- if (FLAG_fields_may_be_reset) {
- return false;
- }
-
- // Since new isolates will be spawned, the JITed code cannot depend on whether
- // global field was initialized when running with --enable-isolate-groups.
- if (FLAG_enable_isolate_groups) return false;
-
- const Field& field = this->field();
- Isolate* only_isolate = IsolateGroup::Current()->FirstIsolate();
- if (only_isolate == nullptr) {
- // This can happen if background compiler executes this code but the mutator
- // is being shutdown and the isolate was already unregistered from the group
- // (and is trying to stop this BG compiler).
- if (field_value != nullptr) {
- *field_value = Object::sentinel().ptr();
- }
- return false;
- }
- if (field_value == nullptr) {
- field_value = &Object::Handle();
- }
- *field_value = only_isolate->field_table()->At(field.field_id());
- return (field_value->ptr() != Object::sentinel().ptr()) &&
- (field_value->ptr() != Object::transition_sentinel().ptr());
-}
-
-Definition* LoadStaticFieldInstr::Canonicalize(FlowGraph* flow_graph) {
- // When precompiling, the fact that a field is currently initialized does not
- // make it safe to omit code that checks if the field needs initialization
- // because the field will be reset so it starts uninitialized in the process
- // running the precompiled code. We must be prepared to reinitialize fields.
- if (calls_initializer() && IsFieldInitialized()) {
- set_calls_initializer(false);
- }
- return this;
-}
-
ConstantInstr::ConstantInstr(const Object& value,
const InstructionSource& source)
: TemplateDefinition(source), value_(value), token_pos_(source.token_pos) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 745412a..62c5fb4 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5577,7 +5577,6 @@
virtual CompileType ComputeType() const;
const Field& field() const { return field_; }
- bool IsFieldInitialized(Object* field_value = nullptr) const;
bool calls_initializer() const { return calls_initializer_; }
void set_calls_initializer(bool value) { calls_initializer_ = value; }
@@ -5601,8 +5600,6 @@
virtual bool CanTriggerGC() const { return calls_initializer(); }
virtual bool MayThrow() const { return calls_initializer(); }
- virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
virtual bool AttributesEqual(const Instruction& other) const;
virtual TokenPosition token_pos() const { return token_pos_; }
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 6f13e1f..75a83b4 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -432,8 +432,6 @@
switch (kind()) {
case kInstanceField:
return instance_field().is_immutable();
- case kStaticField:
- return static_field().is_final() && !FLAG_fields_may_be_reset;
default:
return false;
}
@@ -1542,7 +1540,7 @@
// we should not move them around unless the field is initialized.
// Otherwise we might move load past the initialization.
if (LoadStaticFieldInstr* load = current->AsLoadStaticField()) {
- if (load->AllowsCSE() && !load->IsFieldInitialized()) {
+ if (load->AllowsCSE()) {
seen_visible_effect = true;
continue;
}
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 4e0a257..353fdd7 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -930,10 +930,6 @@
}
)";
- // Make sure static field initialization is not removed because
- // field is already initialized.
- SetFlagScope<bool> sfs(&FLAG_fields_may_be_reset, true);
-
const auto& root_library = Library::Handle(LoadTestScript(kScript));
Invoke(root_library, "main");
const auto& function = Function::Handle(GetFunction(root_library, "foo"));
@@ -979,10 +975,6 @@
}
)";
- // Make sure static field initialization is not removed because
- // field is already initialized.
- SetFlagScope<bool> sfs(&FLAG_fields_may_be_reset, true);
-
const auto& root_library = Library::Handle(LoadTestScript(kScript));
Invoke(root_library, "main");
const auto& function = Function::Handle(GetFunction(root_library, "foo"));
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 2faa89c..8e110dd 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1541,16 +1541,6 @@
is_nullable = false;
}
- auto& obj = Object::Handle();
- const bool is_initialized = IsFieldInitialized(&obj);
- if (field.is_final() && is_initialized) {
- if (!obj.IsNull()) {
- is_nullable = false;
- cid = obj.GetClassId();
- abstract_type = nullptr; // Cid is known, calculate abstract type lazily.
- }
- }
-
if ((field.guarded_cid() != kIllegalCid) &&
(field.guarded_cid() != kDynamicCid)) {
cid = field.guarded_cid();
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index acdb7c6..1ec2adc 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -94,7 +94,6 @@
FLAG_background_compilation = false;
FLAG_enable_mirrors = false;
- FLAG_fields_may_be_reset = true;
FLAG_interpret_irregexp = true;
FLAG_lazy_dispatchers = false;
FLAG_link_natives_lazily = true;
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index a9628b4..224a6b1 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -124,8 +124,6 @@
P(enable_mirrors, bool, true, \
"Disable to make importing dart:mirrors an error.") \
P(enable_ffi, bool, true, "Disable to make importing dart:ffi an error.") \
- P(fields_may_be_reset, bool, false, \
- "Don't optimize away static field initialization") \
P(force_clone_compiler_objects, bool, false, \
"Force cloning of objects needed in compiler (ICData and Field).") \
P(getter_setter_ratio, int, 13, \
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index 49dadd2..d35d1e5 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -466,20 +466,6 @@
PrintFlags();
}
- // TODO(dartbug.com/36097): Support for isolate groups in JIT mode is
- // in-development. We will start with very conservative settings. As we make
- // more of our compiler, runtime as well as generated code re-entrant we'll
- // graudally remove those restrictions.
-
-#if !defined(DART_PRCOMPILED_RUNTIME)
- if (!FLAG_precompiled_mode && FLAG_enable_isolate_groups) {
- // Our compiler should not make rely on a global field being initialized at
- // compile-time, since that compiled code might be re-used in another
- // isolate that has not yet initialized the global field.
- FLAG_fields_may_be_reset = true;
- }
-#endif // !defined(DART_PRCOMPILED_RUNTIME)
-
initialized_ = true;
return NULL;
}
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 4eedcf8..ca14f1f 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -93,6 +93,9 @@
/// Calls the operating system's `stat()` function (or equivalent) on [path].
///
+ /// If [path] is a symbolic link then it is resolved and results for the
+ /// resulting file are returned.
+ ///
/// Returns a [FileStat] object containing the data returned by `stat()`.
/// If the call fails, returns a [FileStat] object with [FileStat.type] set to
/// [FileSystemEntityType.notFound] and the other fields invalid.
@@ -123,6 +126,9 @@
/// Asynchronously calls the operating system's `stat()` function (or
/// equivalent) on [path].
///
+ /// If [path] is a symbolic link then it is resolved and results for the
+ /// resulting file are returned.
+ ///
/// Returns a [Future] which completes with the same results as [statSync].
static Future<FileStat> stat(String path) {
final IOOverrides? overrides = IOOverrides.current;
@@ -356,6 +362,9 @@
/// Returns a `Future<FileStat>` object containing the data returned by
/// `stat()`.
///
+ /// If [path] is a symbolic link then it is resolved and results for the
+ /// resulting file are returned.
+ ///
/// If the call fails, completes the future with a [FileStat] object
/// with `.type` set to [FileSystemEntityType.notFound] and the other fields
/// invalid.
@@ -367,6 +376,9 @@
///
/// Returns a [FileStat] object containing the data returned by `stat()`.
///
+ /// If [path] is a symbolic link then it is resolved and results for the
+ /// resulting file are returned.
+ ///
/// If the call fails, returns a [FileStat] object with `.type` set to
/// [FileSystemEntityType.notFound] and the other fields invalid.
FileStat statSync() => FileStat.statSync(path);
diff --git a/tests/standalone/fields_may_be_reset_test.dart b/tests/standalone/fields_may_be_reset_test.dart
deleted file mode 100644
index 3ab6fc6..0000000
--- a/tests/standalone/fields_may_be_reset_test.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--fields_may_be_reset
-
-main() {
- print("Okay");
-}
diff --git a/tests/standalone/io/file_stat_test.dart b/tests/standalone/io/file_stat_test.dart
index 86054da..8cc3e0e 100644
--- a/tests/standalone/io/file_stat_test.dart
+++ b/tests/standalone/io/file_stat_test.dart
@@ -19,11 +19,16 @@
Expect.equals(FileSystemEntityType.notFound, fileStat.type);
Expect.equals(FileSystemEntityType.notFound, fileStatDirect.type);
file.writeAsStringSync("Dart IO library test of FileStat");
+ Link link = new Link(join(directory.path, "link"));
+ link.createSync(file.path);
new Timer(const Duration(seconds: 2), () {
file.readAsStringSync();
directory.listSync();
FileStat fileStat = FileStat.statSync(file.path);
FileStat fileStatDirect = file.statSync();
+ FileStat linkStat = FileStat.statSync(link.path);
+ FileStat linkStatDirect = link.statSync();
+
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
Expect.equals(FileSystemEntityType.file, fileStatDirect.type);
@@ -44,6 +49,13 @@
directoryStat.changed.compareTo(directoryStat.accessed) < 0);
}
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
+
+ // Verify that statSync resolves the link.
+ Expect.equals(FileSystemEntityType.file, linkStat.type);
+ Expect.equals(32, linkStat.size);
+ Expect.equals(FileSystemEntityType.file, linkStatDirect.type);
+ Expect.equals(32, linkStatDirect.size);
+
directory.deleteSync(recursive: true);
});
}
diff --git a/tests/standalone_2/fields_may_be_reset_test.dart b/tests/standalone_2/fields_may_be_reset_test.dart
deleted file mode 100644
index 7e7f00a..0000000
--- a/tests/standalone_2/fields_may_be_reset_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// @dart = 2.9
-
-// VMOptions=--fields_may_be_reset
-
-main() {
- print("Okay");
-}
diff --git a/tests/standalone_2/io/file_stat_test.dart b/tests/standalone_2/io/file_stat_test.dart
index 9af5190..48b05b2 100644
--- a/tests/standalone_2/io/file_stat_test.dart
+++ b/tests/standalone_2/io/file_stat_test.dart
@@ -21,11 +21,16 @@
Expect.equals(FileSystemEntityType.notFound, fileStat.type);
Expect.equals(FileSystemEntityType.notFound, fileStatDirect.type);
file.writeAsStringSync("Dart IO library test of FileStat");
+ Link link = new Link(join(directory.path, "link"));
+ link.createSync(file.path);
new Timer(const Duration(seconds: 2), () {
file.readAsStringSync();
directory.listSync();
FileStat fileStat = FileStat.statSync(file.path);
FileStat fileStatDirect = file.statSync();
+ FileStat linkStat = FileStat.statSync(link.path);
+ FileStat linkStatDirect = link.statSync();
+
Expect.equals(FileSystemEntityType.file, fileStat.type);
Expect.equals(32, fileStat.size);
Expect.equals(FileSystemEntityType.file, fileStatDirect.type);
@@ -46,6 +51,13 @@
.isTrue(directoryStat.changed.compareTo(directoryStat.accessed) < 0);
}
Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
+
+ // Verify that statSync resolves the link.
+ Expect.equals(FileSystemEntityType.file, linkStat.type);
+ Expect.equals(32, linkStat.size);
+ Expect.equals(FileSystemEntityType.file, linkStatDirect.type);
+ Expect.equals(32, linkStatDirect.size);
+
directory.deleteSync(recursive: true);
});
}
@@ -53,8 +65,7 @@
Future testStatAsync() {
return Directory.systemTemp.createTemp('dart_file_stat').then((directory) {
File file = new File(join(directory.path, "file"));
- return FileStat
- .stat(file.path)
+ return FileStat.stat(file.path)
.then((fileStat) =>
Expect.equals(FileSystemEntityType.notFound, fileStat.type))
.then((_) => file.stat())
diff --git a/tools/VERSION b/tools/VERSION
index 319e2c2..948e5f3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 272
+PRERELEASE 273
PRERELEASE_PATCH 0
\ No newline at end of file