Move delete/deleteSync up to FileSystemEntity, with a shared documentation.

This also means that FileSystemEntity.delete(recursive: true) now will
delete any object on disk, much like 'rm -r', without the need of
wrapping it in a Directory object.

BUG=
R=sgjesse@google.com

Review URL: https://codereview.chromium.org//23889008

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27196 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ajohnsen@google.com 2013-09-05 14:54:38 +00:00
parent 06762131cc
commit 47239cb3a2
9 changed files with 145 additions and 163 deletions

View file

@ -8,7 +8,7 @@ patch class _Directory {
/* patch */ static _createTemp(String template) native "Directory_CreateTemp";
/* patch */ static int _exists(String path) native "Directory_Exists";
/* patch */ static _create(String path) native "Directory_Create";
/* patch */ static _delete(String path, bool recursive)
/* patch */ static _deleteNative(String path, bool recursive)
native "Directory_Delete";
/* patch */ static _rename(String path, String newPath)
native "Directory_Rename";

View file

@ -12,8 +12,8 @@ patch class _File {
/* patch */ static _createLink(String path, String target)
native "File_CreateLink";
/* patch */ static _linkTarget(String path) native "File_LinkTarget";
/* patch */ static _delete(String path) native "File_Delete";
/* patch */ static _deleteLink(String path) native "File_DeleteLink";
/* patch */ static _deleteNative(String path) native "File_Delete";
/* patch */ static _deleteLinkNative(String path) native "File_DeleteLink";
/* patch */ static _rename(String oldPath, String newPath)
native "File_Rename";
/* patch */ static _renameLink(String oldPath, String newPath)

View file

@ -18,8 +18,8 @@ patch class _Directory {
patch static _create(String path) {
throw new UnsupportedError("Directory._create");
}
patch static _delete(String path, bool recursive) {
throw new UnsupportedError("Directory._delete");
patch static _deleteNative(String path, bool recursive) {
throw new UnsupportedError("Directory._deleteNative");
}
patch static _rename(String path, String newPath) {
throw new UnsupportedError("Directory._rename");
@ -74,11 +74,11 @@ patch class _File {
patch static _linkTarget(String path) {
throw new UnsupportedError("File._linkTarget");
}
patch static _delete(String path) {
throw new UnsupportedError("File._delete");
patch static _deleteNative(String path) {
throw new UnsupportedError("File._deleteNative");
}
patch static _deleteLink(String path) {
throw new UnsupportedError("File._deleteLink");
patch static _deleteLinkNative(String path) {
throw new UnsupportedError("File._deleteLinkNative");
}
patch static _rename(String oldPath, String newPath) {
throw new UnsupportedError("File._rename");

View file

@ -88,43 +88,6 @@ abstract class Directory implements FileSystemEntity {
*/
Directory createTempSync();
/**
* Deletes this directory.
*
* If [recursive] is false, the directory must be empty. Only directories
* and links to directories will be deleted.
*
* If [recursive] is true, this directory and all sub-directories
* and files in the directories are deleted. Links are not followed
* when deleting recursively. Only the link is deleted, not its target.
*
* If [recursive] is true, the target is deleted even if it is a file, or
* a link to a file, not only if it is a directory. This behavior allows
* [delete] to be used to unconditionally delete any file system object.
*
* Returns a [:Future<Directory>:] that completes with this
* directory when the deletion is done. If the directory cannot be
* deleted, the future completes with an exception.
*/
Future<Directory> delete({recursive: false});
/**
* Synchronously deletes this directory.
*
* If [recursive] is false, the directory must be empty.
*
* If [recursive] is true, this directory and all sub-directories
* and files in the directories are deleted. Links are not followed
* when deleting recursively. Only the link is deleted, not its target.
*
* If [recursive] is true, the target is deleted even if it is a file, or
* a link to a file, not only if it is a directory. This behavior allows
* [delete] to be used to unconditionally delete any file system object.
*
* Throws an exception if the directory cannot be deleted.
*/
void deleteSync({recursive: false});
/**
* Renames this directory. Returns a [:Future<Directory>:] that completes
* with a [Directory] instance for the renamed directory.

View file

@ -29,7 +29,7 @@ class _Directory extends FileSystemEntity implements Directory {
external static _createTemp(String template);
external static int _exists(String path);
external static _create(String path);
external static _delete(String path, bool recursive);
external static _deleteNative(String path, bool recursive);
external static _rename(String path, String newPath);
external static List _list(String path, bool recursive, bool followLinks);
external static SendPort _newServicePort();
@ -183,7 +183,7 @@ class _Directory extends FileSystemEntity implements Directory {
return new Directory(result);
}
Future<Directory> delete({recursive: false}) {
Future<Directory> _delete({recursive: false}) {
_ensureDirectoryService();
List request = new List(3);
request[0] = DELETE_REQUEST;
@ -197,8 +197,8 @@ class _Directory extends FileSystemEntity implements Directory {
});
}
void deleteSync({recursive: false}) {
var result = _delete(path, recursive);
void _deleteSync({recursive: false}) {
var result = _deleteNative(path, recursive);
if (result is OSError) {
throw new DirectoryException("Deletion failed", path, result);
}

View file

@ -59,21 +59,6 @@ abstract class File implements FileSystemEntity {
*/
void createSync();
/**
* Delete the file. Returns a [:Future<File>:] that completes with
* the file when it has been deleted. Only a file or a link to a file
* can be deleted with this method, not a directory or a broken link.
*/
Future<File> delete();
/**
* Synchronously delete the file. Only a file or a link to a file
* can be deleted with this method, not a directory or a broken link.
*
* Throws a [FileException] if the operation fails.
*/
void deleteSync();
/**
* Renames this file. Returns a `Future<File>` that completes
* with a [File] instance for the renamed file.

View file

@ -295,7 +295,10 @@ class _File extends FileSystemEntity implements File {
throwIfError(result, "Cannot create file", path);
}
Future<File> delete() {
Future<File> _delete({bool recursive: false}) {
if (recursive) {
return new Directory(path).delete(recursive: true).then((_) => this);
}
_ensureFileService();
List request = new List(2);
request[0] = _DELETE_REQUEST;
@ -308,12 +311,15 @@ class _File extends FileSystemEntity implements File {
});
}
external static _delete(String path);
external static _deleteNative(String path);
external static _deleteLink(String path);
external static _deleteLinkNative(String path);
void deleteSync() {
var result = _delete(path);
void _deleteSync({bool recursive: false}) {
if (recursive) {
return new Directory(path).deleteSync(recursive: true);
}
var result = _deleteNative(path);
throwIfError(result, "Cannot delete file", path);
}

View file

@ -168,77 +168,6 @@ FileStat: type $type
abstract class FileSystemEntity {
String get path;
external static _getType(String path, bool followLinks);
external static _identical(String path1, String path2);
static int _getTypeSync(String path, bool followLinks) {
var result = _getType(path, followLinks);
_throwIfError(result, 'Error getting type of FileSystemEntity');
return result;
}
static Future<int> _getTypeAsync(String path, bool followLinks) {
// Get a new file service port for each request. We could also cache one.
var service = _FileUtils._newServicePort();
List request = new List(3);
request[0] = _TYPE_REQUEST;
request[1] = path;
request[2] = followLinks;
return service.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Error getting type", path);
}
return response;
});
}
/**
* Synchronously checks whether two paths refer to the same object in the
* file system. Returns a [:Future<bool>:] that completes with the result.
*
* Comparing a link to its target returns false, as does comparing two links
* that point to the same target. To check the target of a link, use
* Link.target explicitly to fetch it. Directory links appearing
* inside a path are followed, though, to find the file system object.
*
* Completes the returned Future with an error if one of the paths points
* to an object that does not exist.
*/
static Future<bool> identical(String path1, String path2) {
// Get a new file service port for each request. We could also cache one.
var service = _FileUtils._newServicePort();
List request = new List(3);
request[0] = _IDENTICAL_REQUEST;
request[1] = path1;
request[2] = path2;
return service.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Error in FileSystemEntity.identical($path1, $path2)", "");
}
return response;
});
}
/**
* Synchronously checks whether two paths refer to the same object in the
* file system.
*
* Comparing a link to its target returns false, as does comparing two links
* that point to the same target. To check the target of a link, use
* Link.target explicitly to fetch it. Directory links appearing
* inside a path are followed, though, to find the file system object.
*
* Throws an error if one of the paths points to an object that does not
* exist.
*/
static bool identicalSync(String path1, String path2) {
var result = _identical(path1, path2);
_throwIfError(result, 'Error in FileSystemEntity.identicalSync');
return result;
}
/**
* Checks whether the file system entity with this path exists. Returns
* a [:Future<bool>:] that completes with the result.
@ -316,6 +245,45 @@ abstract class FileSystemEntity {
*/
FileStat statSync();
/**
* Deletes this [FileSystemEntity].
*
* If the [FileSystemEntity] is a directory, and if [recursive] is false,
* the directory must be empty. Otherwise, if [recursive] is true, the
* directory and all sub-directories and files in the directories are
* deleted. Links are not followed when deleting recursively. Only the link
* is deleted, not its target.
*
* If [recursive] is true, the [FileSystemEntity] is deleted even if the type
* of the [FileSystemEntity] doesn't match the content of the file system.
* This behavior allows [delete] to be used to unconditionally delete any file
* system object.
*
* Returns a [:Future<FileSystemEntity>:] that completes with this
* [FileSystemEntity] when the deletion is done. If the [FileSystemEntity]
* cannot be deleted, the future completes with an exception.
*/
Future<FileSystemEntity> delete({recursive: false})
=> _delete(recursive: recursive);
/**
* Synchronously deletes this [FileSystemEntity].
*
* If the [FileSystemEntity] is a directory, and if [recursive] is false,
* the directory must be empty. Otherwise, if [recursive] is true, the
* directory and all sub-directories and files in the directories are
* deleted. Links are not followed when deleting recursively. Only the link
* is deleted, not its target.
*
* If [recursive] is true, the [FileSystemEntity] is deleted even if the type
* of the [FileSystemEntity] doesn't match the content of the file system.
* This behavior allows [deleteSync] to be used to unconditionally delete any
* file system object.
*
* Throws an exception if the [FileSystemEntity] cannot be deleted.
*/
void deleteSync({recursive: false})
=> _deleteSync(recursive: recursive);
/**
@ -344,6 +312,56 @@ abstract class FileSystemEntity {
events,
recursive).stream;
Future<FileSystemEntity> _delete({recursive: false});
void _deleteSync({recursive: false});
/**
* Synchronously checks whether two paths refer to the same object in the
* file system. Returns a [:Future<bool>:] that completes with the result.
*
* Comparing a link to its target returns false, as does comparing two links
* that point to the same target. To check the target of a link, use
* Link.target explicitly to fetch it. Directory links appearing
* inside a path are followed, though, to find the file system object.
*
* Completes the returned Future with an error if one of the paths points
* to an object that does not exist.
*/
static Future<bool> identical(String path1, String path2) {
// Get a new file service port for each request. We could also cache one.
var service = _FileUtils._newServicePort();
List request = new List(3);
request[0] = _IDENTICAL_REQUEST;
request[1] = path1;
request[2] = path2;
return service.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
"Error in FileSystemEntity.identical($path1, $path2)", "");
}
return response;
});
}
/**
* Synchronously checks whether two paths refer to the same object in the
* file system.
*
* Comparing a link to its target returns false, as does comparing two links
* that point to the same target. To check the target of a link, use
* Link.target explicitly to fetch it. Directory links appearing
* inside a path are followed, though, to find the file system object.
*
* Throws an error if one of the paths points to an object that does not
* exist.
*/
static bool identicalSync(String path1, String path2) {
var result = _identical(path1, path2);
_throwIfError(result, 'Error in FileSystemEntity.identicalSync');
return result;
}
/**
* Test if [watch] is supported on the current system.
*
@ -351,7 +369,6 @@ abstract class FileSystemEntity {
*/
static bool get isWatchSupported => _FileSystemWatcher.isSupported;
/**
* Finds the type of file system object that a path points to. Returns
* a [:Future<FileSystemEntityType>:] that completes with the result.
@ -383,7 +400,6 @@ abstract class FileSystemEntity {
static FileSystemEntityType typeSync(String path, {bool followLinks: true})
=> FileSystemEntityType._lookup(_getTypeSync(path, followLinks));
/**
* Checks if type(path, followLinks: false) returns
* FileSystemEntityType.LINK.
@ -424,6 +440,29 @@ abstract class FileSystemEntity {
static bool isDirectorySync(String path) =>
(_getTypeSync(path, true) == FileSystemEntityType.DIRECTORY._type);
external static _getType(String path, bool followLinks);
external static _identical(String path1, String path2);
static int _getTypeSync(String path, bool followLinks) {
var result = _getType(path, followLinks);
_throwIfError(result, 'Error getting type of FileSystemEntity');
return result;
}
static Future<int> _getTypeAsync(String path, bool followLinks) {
// Get a new file service port for each request. We could also cache one.
var service = _FileUtils._newServicePort();
List request = new List(3);
request[0] = _TYPE_REQUEST;
request[1] = path;
request[2] = followLinks;
return service.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response, "Error getting type", path);
}
return response;
});
}
static _throwIfError(Object result, String msg, [String path]) {
if (result is OSError) {

View file

@ -64,23 +64,6 @@ abstract class Link implements FileSystemEntity {
*/
Future<Link> update(String target);
/**
* Deletes the link. Returns a [:Future<Link>:] that completes with
* the link when it has been deleted. This does not delete, or otherwise
* affect, the target of the link. It also works on broken links, but if
* the link does not exist or is not actually a link, it completes the
* future with a LinkException.
*/
Future<Link> delete();
/**
* Synchronously deletes the link. This does not delete, or otherwise
* affect, the target of the link. It also works on broken links, but if
* the link does not exist or is not actually a link, it throws a
* LinkException.
*/
void deleteSync();
/**
* Renames this link. Returns a `Future<Link>` that completes
* with a [Link] instance for the renamed link.
@ -213,7 +196,10 @@ class _Link extends FileSystemEntity implements Link {
return delete().then((_) => create(target));
}
Future<Link> delete() {
Future<Link> _delete({bool recursive: false}) {
if (recursive) {
return new Directory(path).delete(recursive: true).then((_) => this);
}
_ensureFileService();
List request = new List(2);
request[0] = _DELETE_LINK_REQUEST;
@ -226,8 +212,11 @@ class _Link extends FileSystemEntity implements Link {
});
}
void deleteSync() {
var result = _File._deleteLink(path);
void _deleteSync({bool recursive: false}) {
if (recursive) {
return new Directory(path).deleteSync(recursive: true);
}
var result = _File._deleteLinkNative(path);
throwIfError(result, "Cannot delete link", path);
}