diff --git a/doc/site/modules/io/file.markdown b/doc/site/modules/io/file.markdown
index cb32454e..9cd717fb 100644
--- a/doc/site/modules/io/file.markdown
+++ b/doc/site/modules/io/file.markdown
@@ -35,13 +35,6 @@ whatever encoding the file uses.
Returns the size in bytes of the contents of the file at `path`.
-### File.**stat**(path)
-
-"Stats" the file or directory at `path`. Returns a [Stat][] object describing
-the low-level details of the file system entry.
-
-[stat]: stat.html
-
## Constructors
### File.**open**(path)
diff --git a/doc/site/modules/io/stat.markdown b/doc/site/modules/io/stat.markdown
index 0b69b219..e62bb319 100644
--- a/doc/site/modules/io/stat.markdown
+++ b/doc/site/modules/io/stat.markdown
@@ -1,8 +1,12 @@
^title Stat Class
-Contains the data returned by [File.stat()][stat].
+A data structure describing the low-level details of a file system entry.
-[stat]: file.html#file.stat(path)
+## Static Methods
+
+### Stat.**path**(path)
+
+"Stats" the file or directory at `path`.
## Methods
diff --git a/doc/site/modules/io/template.html b/doc/site/modules/io/template.html
index ebce39a1..84ef8b93 100644
--- a/doc/site/modules/io/template.html
+++ b/doc/site/modules/io/template.html
@@ -29,6 +29,7 @@
@@ -45,11 +46,13 @@
|
|
|
diff --git a/src/cli/modules.c b/src/cli/modules.c
index a0cdf5d4..16dea2c1 100644
--- a/src/cli/modules.c
+++ b/src/cli/modules.c
@@ -13,12 +13,12 @@ extern void fileAllocate(WrenVM* vm);
extern void fileFinalize(void* data);
extern void fileOpen(WrenVM* vm);
extern void fileSizePath(WrenVM* vm);
-extern void fileStatPath(WrenVM* vm);
extern void fileClose(WrenVM* vm);
extern void fileDescriptor(WrenVM* vm);
extern void fileReadBytes(WrenVM* vm);
extern void fileSize(WrenVM* vm);
extern void processAllArguments(WrenVM* vm);
+extern void statPath(WrenVM* vm);
extern void stdinReadStart(WrenVM* vm);
extern void stdinReadStop(WrenVM* vm);
extern void schedulerCaptureMethods(WrenVM* vm);
@@ -39,7 +39,7 @@ extern void timerStartTimer(WrenVM* vm);
// If you add a new class to the largest module below, make sure to bump this.
// Note that it also includes an extra slot for the sentinel value indicating
// the end of the list.
-#define MAX_CLASSES_PER_MODULE 4
+#define MAX_CLASSES_PER_MODULE 5
// Describes one foreign method in a class.
typedef struct
@@ -100,12 +100,14 @@ static ModuleRegistry modules[] =
FINALIZER(fileFinalize)
STATIC_METHOD("open_(_,_)", fileOpen)
STATIC_METHOD("sizePath_(_,_)", fileSizePath)
- STATIC_METHOD("statPath_(_,_)", fileStatPath)
METHOD("close_(_)", fileClose)
METHOD("descriptor", fileDescriptor)
METHOD("readBytes_(_,_,_)", fileReadBytes)
METHOD("size_(_)", fileSize)
END_CLASS
+ CLASS(Stat)
+ STATIC_METHOD("path_(_,_)", statPath)
+ END_CLASS
CLASS(Stdin)
STATIC_METHOD("readStart_()", stdinReadStart)
STATIC_METHOD("readStop_()", stdinReadStop)
diff --git a/src/module/io.c b/src/module/io.c
index 8e52449d..35ffa301 100644
--- a/src/module/io.c
+++ b/src/module/io.c
@@ -188,62 +188,6 @@ void fileSizePath(WrenVM* vm)
uv_fs_stat(getLoop(), request, path, fileSizeCallback);
}
-// Called by libuv when the stat call completes.
-static void fileStatPathCallback(uv_fs_t* request)
-{
- if (handleRequestError(request)) return;
-
- WrenVM* vm = getVM();
- wrenEnsureSlots(vm, 4);
- wrenSetSlotNewList(vm, 2);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_dev);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_ino);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_mode);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_nlink);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_uid);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_gid);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_rdev);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_size);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blksize);
- wrenInsertInList(vm, 2, -1, 3);
-
- wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blocks);
- wrenInsertInList(vm, 2, -1, 3);
-
- // TODO: Include access, modification, and change times once we figure out
- // how we want to represent it.
- // time_t st_atime; /* time of last access */
- // time_t st_mtime; /* time of last modification */
- // time_t st_ctime; /* time of last status change */
-
- schedulerResume(freeRequest(request), true);
- schedulerFinishResume();
-}
-
-void fileStatPath(WrenVM* vm)
-{
- const char* path = wrenGetSlotString(vm, 1);
- uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
- uv_fs_stat(getLoop(), request, path, fileStatPathCallback);
-}
-
static void fileCloseCallback(uv_fs_t* request)
{
if (handleRequestError(request)) return;
@@ -325,6 +269,62 @@ void fileSize(WrenVM* vm)
uv_fs_fstat(getLoop(), request, fd, fileSizeCallback);
}
+// Called by libuv when the stat call completes.
+static void statPathCallback(uv_fs_t* request)
+{
+ if (handleRequestError(request)) return;
+
+ WrenVM* vm = getVM();
+ wrenEnsureSlots(vm, 4);
+ wrenSetSlotNewList(vm, 2);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_dev);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_ino);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_mode);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_nlink);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_uid);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_gid);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_rdev);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_size);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blksize);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ wrenSetSlotDouble(vm, 3, (double)request->statbuf.st_blocks);
+ wrenInsertInList(vm, 2, -1, 3);
+
+ // TODO: Include access, modification, and change times once we figure out
+ // how we want to represent it.
+ // time_t st_atime; /* time of last access */
+ // time_t st_mtime; /* time of last modification */
+ // time_t st_ctime; /* time of last status change */
+
+ schedulerResume(freeRequest(request), true);
+ schedulerFinishResume();
+}
+
+void statPath(WrenVM* vm)
+{
+ const char* path = wrenGetSlotString(vm, 1);
+ uv_fs_t* request = createRequest(wrenGetSlotValue(vm, 2));
+ uv_fs_stat(getLoop(), request, path, statPathCallback);
+}
+
static void allocCallback(uv_handle_t* handle, size_t suggestedSize,
uv_buf_t* buf)
{
diff --git a/src/module/io.wren b/src/module/io.wren
index e501c67a..541de4ae 100644
--- a/src/module/io.wren
+++ b/src/module/io.wren
@@ -44,13 +44,6 @@ foreign class File {
return Scheduler.runNextScheduled_()
}
- static stat(path) {
- if (!(path is String)) Fiber.abort("Path must be a string.")
-
- statPath_(path, Fiber.current)
- return Stat.new_(Scheduler.runNextScheduled_())
- }
-
construct new_(fd) {}
close() {
@@ -87,7 +80,6 @@ foreign class File {
foreign static open_(path, fiber)
foreign static sizePath_(path, fiber)
- foreign static statPath_(path, fiber)
foreign close_(fiber)
foreign readBytes_(count, start, fiber)
@@ -99,6 +91,13 @@ class Stat {
_fields = fields
}
+ static path(path) {
+ if (!(path is String)) Fiber.abort("Path must be a string.")
+
+ path_(path, Fiber.current)
+ return Stat.new_(Scheduler.runNextScheduled_())
+ }
+
device { _fields[0] }
inode { _fields[1] }
mode { _fields[2] }
@@ -109,6 +108,8 @@ class Stat {
size { _fields[7] }
blockSize { _fields[8] }
blockCount { _fields[9] }
+
+ foreign static path_(path, fiber)
}
class Stdin {
diff --git a/src/module/io.wren.inc b/src/module/io.wren.inc
index 6f83dc7b..7f78f1b0 100644
--- a/src/module/io.wren.inc
+++ b/src/module/io.wren.inc
@@ -46,13 +46,6 @@ static const char* ioModuleSource =
" return Scheduler.runNextScheduled_()\n"
" }\n"
"\n"
-" static stat(path) {\n"
-" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
-"\n"
-" statPath_(path, Fiber.current)\n"
-" return Stat.new_(Scheduler.runNextScheduled_())\n"
-" }\n"
-"\n"
" construct new_(fd) {}\n"
"\n"
" close() {\n"
@@ -89,7 +82,6 @@ static const char* ioModuleSource =
"\n"
" foreign static open_(path, fiber)\n"
" foreign static sizePath_(path, fiber)\n"
-" foreign static statPath_(path, fiber)\n"
"\n"
" foreign close_(fiber)\n"
" foreign readBytes_(count, start, fiber)\n"
@@ -101,6 +93,13 @@ static const char* ioModuleSource =
" _fields = fields\n"
" }\n"
"\n"
+" static path(path) {\n"
+" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
+"\n"
+" path_(path, Fiber.current)\n"
+" return Stat.new_(Scheduler.runNextScheduled_())\n"
+" }\n"
+"\n"
" device { _fields[0] }\n"
" inode { _fields[1] }\n"
" mode { _fields[2] }\n"
@@ -111,6 +110,8 @@ static const char* ioModuleSource =
" size { _fields[7] }\n"
" blockSize { _fields[8] }\n"
" blockCount { _fields[9] }\n"
+"\n"
+" foreign static path_(path, fiber)\n"
"}\n"
"\n"
"class Stdin {\n"
diff --git a/test/io/file/stat_static_nonexistent.wren b/test/io/file/stat_static_nonexistent.wren
deleted file mode 100644
index 8bc17802..00000000
--- a/test/io/file/stat_static_nonexistent.wren
+++ /dev/null
@@ -1,3 +0,0 @@
-import "io" for File
-
-File.stat("nonexistent") // expect runtime error: no such file or directory
diff --git a/test/io/file/stat_static.wren b/test/io/stat/path.wren
similarity index 89%
rename from test/io/file/stat_static.wren
rename to test/io/stat/path.wren
index 0ca59d3f..f594eed4 100644
--- a/test/io/file/stat_static.wren
+++ b/test/io/stat/path.wren
@@ -1,7 +1,7 @@
-import "io" for File, Stat
+import "io" for Stat
import "scheduler" for Scheduler
-var stat = File.stat("test/io/file/file.txt")
+var stat = Stat.path("test/io/file/file.txt")
System.print(stat is Stat) // expect: true
System.print(stat.device is Num) // expect: true
diff --git a/test/io/file/stat_static_directory.wren b/test/io/stat/path_directory.wren
similarity index 89%
rename from test/io/file/stat_static_directory.wren
rename to test/io/stat/path_directory.wren
index 4521d105..38224948 100644
--- a/test/io/file/stat_static_directory.wren
+++ b/test/io/stat/path_directory.wren
@@ -1,7 +1,7 @@
-import "io" for File, Stat
+import "io" for Stat
import "scheduler" for Scheduler
-var stat = File.stat("test/io/directory/dir")
+var stat = Stat.path("test/io/directory/dir")
System.print(stat is Stat) // expect: true
System.print(stat.device is Num) // expect: true
diff --git a/test/io/stat/path_nonexistent.wren b/test/io/stat/path_nonexistent.wren
new file mode 100644
index 00000000..567c73ba
--- /dev/null
+++ b/test/io/stat/path_nonexistent.wren
@@ -0,0 +1,3 @@
+import "io" for Stat
+
+Stat.path("nonexistent") // expect runtime error: no such file or directory