Skip to content

Commit

Permalink
Version 3.3.0-62.0.dev
Browse files Browse the repository at this point in the history
Merge 8ab0325 into dev
  • Loading branch information
Dart CI committed Oct 26, 2023
2 parents 0757551 + 8ab0325 commit 0b4e241
Show file tree
Hide file tree
Showing 16 changed files with 140 additions and 170 deletions.
11 changes: 8 additions & 3 deletions runtime/bin/file_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,12 @@ File::Type File::GetType(Namespace* namespc,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (target_handle == INVALID_HANDLE_VALUE) {
result = File::kIsLink;
DWORD last_error = GetLastError();
if ((last_error == ERROR_FILE_NOT_FOUND) ||
(last_error == ERROR_PATH_NOT_FOUND)) {
return kDoesNotExist;
}
result = kIsLink;
} else {
BY_HANDLE_FILE_INFORMATION info;
if (!GetFileInformationByHandle(target_handle, &info)) {
Expand All @@ -1139,8 +1144,8 @@ File::Type File::GetType(Namespace* namespc,
}
CloseHandle(target_handle);
return ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
? File::kIsDirectory
: File::kIsFile;
? kIsDirectory
: kIsFile;
}
} else {
result = kIsLink;
Expand Down
2 changes: 1 addition & 1 deletion runtime/observatory/tests/ui/inspector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class Node {
extractPrivateField(reflectClass(A).typeVariables.single, '_reflectee');
typedDataArray = Uint8List(32);
typedDataView = Uint8List.view(typedDataArray.buffer, 16);
typedDataUnmodifiableView = UnmodifiableUint8ListView(typedDataArray);
typedDataUnmodifiableView = typedDataArray.asUnmodifiableView();
userTag = new UserTag("Example tag name");
weakProperty =
extractPrivateField(expando, '_data').firstWhere((e) => e != null);
Expand Down
19 changes: 16 additions & 3 deletions sdk/lib/io/file_system_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ abstract class FileSystemEntity {
/// ```
/// since `Uri.resolve` removes `..` segments. This will result in the Windows
/// behavior.
///
/// On Windows, attempting to resolve a symbolic link where the link type
/// does not match the type of the resolved file system object will cause the
/// Future to complete with a [PathAccessException] error.
Future<String> resolveSymbolicLinks() {
return _File._dispatchWithNamespace(
_IOService.fileResolveSymbolicLinks, [null, _rawPath]).then((response) {
Expand Down Expand Up @@ -343,6 +347,11 @@ abstract class FileSystemEntity {
/// ```
/// since `Uri.resolve` removes `..` segments. This will result in the Windows
/// behavior.
///
/// On Windows, a symbolic link is created as either a file link or a
/// directory link. Attempting to resolve such a symbolic link requires the
/// link type to match the type of the file system object that it points to,
/// otherwise it throws a [PathAccessException].
String resolveSymbolicLinksSync() {
var result = _resolveSymbolicLinks(_Namespace._namespace, _rawPath);
_throwIfError(result, "Cannot resolve symbolic links", path);
Expand Down Expand Up @@ -685,11 +694,15 @@ abstract class FileSystemEntity {

/// Synchronously finds the type of file system object that a path points to.
///
/// Returns [FileSystemEntityType.link] only if [followLinks] is `false` and if
/// [path] points to a link.
///
/// Returns [FileSystemEntityType.notFound] if [path] does not point to a file
/// system object or if any other error occurs in looking up the path.
///
/// If [path] points to a link and [followLinks] is `true` then the result
/// will be for the file system object that the link points to. If that
/// object does not exist then the result will be
/// [FileSystemEntityType.notFound]. If [path] points to a link and
/// [followLinks] is `false` then the result will be
/// [FileSystemEntityType.link].
static FileSystemEntityType typeSync(String path, {bool followLinks = true}) {
return _getTypeSync(_toUtf8Array(path), followLinks);
}
Expand Down
54 changes: 40 additions & 14 deletions sdk/lib/io/link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,20 @@ abstract interface class Link implements FileSystemEntity {
/// not affected, unless they are also in [path].
///
/// On the Windows platform, this call will create a true symbolic link
/// instead of a junction. The link represents a file or directory and
/// does not change its type after creation. If [target] exists then
/// the type of the link will match the type [target], otherwise a file
/// symlink is created.
/// instead of a junction. Windows treats links to files and links to
/// directories as different and non-interchangable kinds of links.
/// Each link is either a file-link or a directory-link, and the type is
/// chosen when the link is created, and the link then counts as either a
/// file or directory for most purposes. Different Win32 API calls are
/// used to manipulate each. For example, the `DeleteFile` function is
/// used to delete links to files, and `RemoveDirectory` must be used to
/// delete links to directories.
///
/// The created Windows symbolic link will match the type of the [target],
/// if [target] exists, otherwise a file-link is created. The type of the
/// created link will not change if [target] is later replaced by something
/// of a different type and the link will not be resolvable by
/// [resolveSymbolicLinks].
///
/// In order to create a symbolic link on Windows, Dart must be run in
/// Administrator mode or the system must have Developer Mode enabled,
Expand All @@ -76,10 +86,20 @@ abstract interface class Link implements FileSystemEntity {
/// the path of [target] are not affected, unless they are also in [path].
///
/// On the Windows platform, this call will create a true symbolic link
/// instead of a junction. The link represents a file or directory and
/// does not change its type after creation. If [target] exists then
/// the type of the link will match the type [target], otherwise a file
/// symlink is created.
/// instead of a junction. Windows treats links to files and links to
/// directories as different and non-interchangable kinds of links.
/// Each link is either a file-link or a directory-link, and the type is
/// chosen when the link is created, and the link then counts as either a
/// file or directory for most purposes. Different Win32 API calls are
/// used to manipulate each. For example, the `DeleteFile` function is
/// used to delete links to files, and `RemoveDirectory` must be used to
/// delete links to directories.
///
/// The created Windows symbolic link will match the type of the [target],
/// if [target] exists, otherwise a file-link is created. The type of the
/// created link will not change if [target] is later replaced by something
/// of a different type and the link will not be resolvable by
/// [resolveSymbolicLinks].
///
/// In order to create a symbolic link on Windows, Dart must be run in
/// Administrator mode or the system must have Developer Mode enabled,
Expand All @@ -91,16 +111,22 @@ abstract interface class Link implements FileSystemEntity {
/// it will be interpreted relative to the directory containing the link.
void createSync(String target, {bool recursive = false});

/// Synchronously updates the link.
/// Synchronously updates an existing link.
///
/// Calling [updateSync] on a non-existing link will throw an exception.
/// Deletes the existing link at [path] and uses [createSync] to create a new
/// link to [target]. Throws [PathNotFoundException] if the original link
/// does not exist or with any [FileSystemException] that [deleteSync] or
/// [createSync] can throw.
void updateSync(String target);

/// Updates the link.
/// Updates an existing link.
///
/// Deletes the existing link at [path] and creates a new link to [target],
/// using [create].
///
/// Returns a `Future<Link>` that completes with the
/// link when it has been updated. Calling [update] on a non-existing link
/// will complete its returned future with an exception.
/// Returns a future which completes with this `Link` if successful,
/// and with a [PathNotFoundException] if there is no existing link at [path],
/// or with any [FileSystemException] that [delete] or [create] can throw.
Future<Link> update(String target);

Future<String> resolveSymbolicLinks();
Expand Down
6 changes: 4 additions & 2 deletions tests/lib/async/periodic_timer2_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ expectGTE(min, actual, msg) {
}

main() {
int interval = 20;
int interval = 50;
asyncStart();
var sw = new Stopwatch()..start();
int nextTick = 1;
new Timer.periodic(ms * interval, (t) {
expectGTE(nextTick, t.tick, "tick {1} before expect next tick {0}.");
nextTick = t.tick + 1; // Always increment tick by at least one.
int time = sw.elapsedMilliseconds;
int minTime = interval * t.tick;
// Timers are not exact and can fire early or late (+- 15ms), we add a
// margin of error (40ms) to avoid flakiness.
int minTime = interval * t.tick - 40;
expectGTE(minTime, time, "Actual time {1} before {0} at tick ${t.tick}");
if (t.tick > 20) {
t.cancel();
Expand Down
6 changes: 4 additions & 2 deletions tests/lib/async/periodic_timer3_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ expectGTE(min, actual, msg) {
}

main() {
int interval = 20;
int interval = 50;
asyncStart();
var sw = new Stopwatch()..start();
int nextTick = 1;
new Timer.periodic(ms * interval, (t) {
expectGTE(nextTick, t.tick, "tick {1} before expect next tick {0}.");
int time = sw.elapsedMilliseconds;
int minTime = interval * t.tick;
// Timers are not exact and can fire early or late (+- 15ms), we add a
// margin of error (40ms) to avoid flakiness.
int minTime = interval * t.tick - 40;
expectGTE(minTime, time, "Actual time {1} before {0} at tick ${t.tick}");
while (sw.elapsedMilliseconds < time + 3 * interval) {
// idle.
Expand Down
6 changes: 4 additions & 2 deletions tests/lib/async/periodic_timer4_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ expectGTE(min, actual, msg) {
}

main() {
int interval = 20;
int interval = 50;
asyncStart();
var sw = new Stopwatch()..start();
int nextTick = 1;
Expand All @@ -25,7 +25,9 @@ main() {
expectGTE(nextTick, t.tick, "tick {1} before expect next tick {0}.");
nextTick += 1;
int time = sw.elapsedMilliseconds;
int minTime = interval * t.tick;
// Timers are not exact and can fire early or late (+- 15ms), we add a
// margin of error (40ms) to avoid flakiness.
int minTime = interval * t.tick - 40;
expectGTE(minTime, time, "Actual time {1} before {0} at tick ${t.tick}");
if (t.tick > 20) {
running = false;
Expand Down
70 changes: 0 additions & 70 deletions tests/lib/html/native_gc_test.dart

This file was deleted.

68 changes: 0 additions & 68 deletions tests/lib_2/html/native_gc_test.dart

This file was deleted.

13 changes: 13 additions & 0 deletions tests/standalone/io/link_async_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,24 @@ Future testRelativeLinks(_) {
});
}

Future testBrokenLinkTypeSync(_) async {
String base = (await Directory.systemTemp.createTemp('dart_link')).path;
String link = join(base, 'link');
await Link(link).create('does not exist');

Expect.equals(FileSystemEntityType.link,
await FileSystemEntity.type(link, followLinks: false));

Expect.equals(FileSystemEntityType.notFound,
await FileSystemEntity.type(link, followLinks: true));
}

main() {
asyncStart();
testCreate()
.then(testCreateLoopingLink)
.then(testRename)
.then(testRelativeLinks)
.then(testBrokenLinkTypeSync)
.then((_) => asyncEnd());
}
Loading

0 comments on commit 0b4e241

Please sign in to comment.