goscript 0.0.26 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/cmd/goscript/cmd_compile.go +0 -3
- package/cmd/goscript/deps.go +11 -0
- package/compiler/analysis.go +298 -55
- package/compiler/assignment.go +2 -2
- package/compiler/builtin_test.go +1 -1
- package/compiler/compiler.go +200 -68
- package/compiler/compiler_test.go +17 -24
- package/compiler/composite-lit.go +32 -8
- package/compiler/decl.go +6 -6
- package/compiler/expr-call.go +170 -15
- package/compiler/expr-selector.go +100 -0
- package/compiler/expr.go +1 -1
- package/compiler/protobuf.go +557 -0
- package/compiler/spec-struct.go +4 -0
- package/compiler/spec-value.go +89 -10
- package/compiler/spec.go +254 -1
- package/compiler/stmt-assign.go +35 -0
- package/compiler/type-assert.go +87 -0
- package/compiler/type.go +4 -1
- package/dist/gs/builtin/builtin.d.ts +20 -1
- package/dist/gs/builtin/builtin.js +95 -4
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +1 -1
- package/dist/gs/builtin/slice.js +21 -2
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +5 -6
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/internal/oserror/errors.d.ts +6 -0
- package/dist/gs/internal/oserror/errors.js +7 -0
- package/dist/gs/internal/oserror/errors.js.map +1 -0
- package/dist/gs/internal/oserror/index.d.ts +1 -0
- package/dist/gs/internal/oserror/index.js +2 -0
- package/dist/gs/internal/oserror/index.js.map +1 -0
- package/dist/gs/io/fs/format.d.ts +3 -0
- package/dist/gs/io/fs/format.js +56 -0
- package/dist/gs/io/fs/format.js.map +1 -0
- package/dist/gs/io/fs/fs.d.ts +79 -0
- package/dist/gs/io/fs/fs.js +200 -0
- package/dist/gs/io/fs/fs.js.map +1 -0
- package/dist/gs/io/fs/glob.d.ts +10 -0
- package/dist/gs/io/fs/glob.js +141 -0
- package/dist/gs/io/fs/glob.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +8 -0
- package/dist/gs/io/fs/index.js +9 -0
- package/dist/gs/io/fs/index.js.map +1 -0
- package/dist/gs/io/fs/readdir.d.ts +7 -0
- package/dist/gs/io/fs/readdir.js +152 -0
- package/dist/gs/io/fs/readdir.js.map +1 -0
- package/dist/gs/io/fs/readfile.d.ts +6 -0
- package/dist/gs/io/fs/readfile.js +118 -0
- package/dist/gs/io/fs/readfile.js.map +1 -0
- package/dist/gs/io/fs/stat.d.ts +6 -0
- package/dist/gs/io/fs/stat.js +87 -0
- package/dist/gs/io/fs/stat.js.map +1 -0
- package/dist/gs/io/fs/sub.d.ts +6 -0
- package/dist/gs/io/fs/sub.js +172 -0
- package/dist/gs/io/fs/sub.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +7 -0
- package/dist/gs/io/fs/walk.js +76 -0
- package/dist/gs/io/fs/walk.js.map +1 -0
- package/dist/gs/io/index.d.ts +1 -0
- package/dist/gs/io/index.js +2 -0
- package/dist/gs/io/index.js.map +1 -0
- package/dist/gs/io/io.d.ts +107 -0
- package/dist/gs/io/io.js +385 -0
- package/dist/gs/io/io.js.map +1 -0
- package/dist/gs/path/index.d.ts +2 -0
- package/dist/gs/path/index.js +3 -0
- package/dist/gs/path/index.js.map +1 -0
- package/dist/gs/path/match.d.ts +6 -0
- package/dist/gs/path/match.js +281 -0
- package/dist/gs/path/match.js.map +1 -0
- package/dist/gs/path/path.d.ts +7 -0
- package/dist/gs/path/path.js +256 -0
- package/dist/gs/path/path.js.map +1 -0
- package/dist/gs/strings/builder.d.ts +18 -0
- package/dist/gs/strings/builder.js +205 -0
- package/dist/gs/strings/builder.js.map +1 -0
- package/dist/gs/strings/clone.d.ts +1 -0
- package/dist/gs/strings/clone.js +16 -0
- package/dist/gs/strings/clone.js.map +1 -0
- package/dist/gs/strings/compare.d.ts +1 -0
- package/dist/gs/strings/compare.js +14 -0
- package/dist/gs/strings/compare.js.map +1 -0
- package/dist/gs/strings/index.d.ts +2 -0
- package/dist/gs/strings/index.js +3 -0
- package/dist/gs/strings/index.js.map +1 -0
- package/dist/gs/strings/iter.d.ts +8 -0
- package/dist/gs/strings/iter.js +160 -0
- package/dist/gs/strings/iter.js.map +1 -0
- package/dist/gs/strings/reader.d.ts +34 -0
- package/dist/gs/strings/reader.js +418 -0
- package/dist/gs/strings/reader.js.map +1 -0
- package/dist/gs/strings/replace.d.ts +106 -0
- package/dist/gs/strings/replace.js +1136 -0
- package/dist/gs/strings/replace.js.map +1 -0
- package/dist/gs/strings/search.d.ts +24 -0
- package/dist/gs/strings/search.js +169 -0
- package/dist/gs/strings/search.js.map +1 -0
- package/dist/gs/strings/strings.d.ts +47 -0
- package/dist/gs/strings/strings.js +418 -0
- package/dist/gs/strings/strings.js.map +1 -0
- package/dist/gs/stringslite/index.d.ts +1 -0
- package/dist/gs/stringslite/index.js +2 -0
- package/dist/gs/stringslite/index.js.map +1 -0
- package/dist/gs/stringslite/strings.d.ts +11 -0
- package/dist/gs/stringslite/strings.js +67 -0
- package/dist/gs/stringslite/strings.js.map +1 -0
- package/dist/gs/sync/index.d.ts +1 -0
- package/dist/gs/sync/index.js +2 -0
- package/dist/gs/sync/index.js.map +1 -0
- package/dist/gs/sync/sync.d.ts +79 -0
- package/dist/gs/sync/sync.js +392 -0
- package/dist/gs/sync/sync.js.map +1 -0
- package/dist/gs/time/time.d.ts +11 -2
- package/dist/gs/time/time.js +337 -12
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/index.d.ts +1 -0
- package/dist/gs/unicode/index.js +2 -0
- package/dist/gs/unicode/index.js.map +1 -0
- package/dist/gs/unicode/unicode.d.ts +105 -0
- package/dist/gs/unicode/unicode.js +332 -0
- package/dist/gs/unicode/unicode.js.map +1 -0
- package/dist/gs/unicode/utf8/index.d.ts +1 -0
- package/dist/gs/unicode/utf8/index.js +3 -0
- package/dist/gs/unicode/utf8/index.js.map +1 -0
- package/dist/gs/unicode/utf8/utf8.d.ts +20 -0
- package/dist/gs/unicode/utf8/utf8.js +196 -0
- package/dist/gs/unicode/utf8/utf8.js.map +1 -0
- package/dist/gs/unsafe/index.d.ts +1 -0
- package/dist/gs/unsafe/index.js +2 -0
- package/dist/gs/unsafe/index.js.map +1 -0
- package/dist/gs/unsafe/unsafe.d.ts +11 -0
- package/dist/gs/unsafe/unsafe.js +44 -0
- package/dist/gs/unsafe/unsafe.js.map +1 -0
- package/go.mod +2 -1
- package/go.sum +6 -2
- package/gs/README.md +6 -0
- package/gs/builtin/builtin.ts +171 -0
- package/gs/builtin/channel.ts +683 -0
- package/gs/builtin/defer.ts +58 -0
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/io.ts +22 -0
- package/gs/builtin/map.ts +50 -0
- package/gs/builtin/slice.ts +1030 -0
- package/gs/builtin/type.ts +1106 -0
- package/gs/builtin/varRef.ts +25 -0
- package/gs/cmp/godoc.txt +8 -0
- package/gs/cmp/index.ts +29 -0
- package/gs/context/context.ts +401 -0
- package/gs/context/godoc.txt +69 -0
- package/gs/context/index.ts +1 -0
- package/gs/errors/errors.ts +223 -0
- package/gs/errors/godoc.txt +63 -0
- package/gs/errors/index.ts +1 -0
- package/gs/internal/goarch/godoc.txt +39 -0
- package/gs/internal/goarch/index.ts +18 -0
- package/gs/internal/oserror/errors.ts +14 -0
- package/gs/internal/oserror/index.ts +1 -0
- package/gs/io/fs/format.ts +65 -0
- package/gs/io/fs/fs.ts +359 -0
- package/gs/io/fs/glob.ts +167 -0
- package/gs/io/fs/godoc.txt +35 -0
- package/gs/io/fs/index.ts +8 -0
- package/gs/io/fs/readdir.ts +126 -0
- package/gs/io/fs/readfile.ts +77 -0
- package/gs/io/fs/stat.ts +38 -0
- package/gs/io/fs/sub.ts +208 -0
- package/gs/io/fs/walk.ts +89 -0
- package/gs/io/godoc.txt +61 -0
- package/gs/io/index.ts +1 -0
- package/gs/io/io.go +75 -0
- package/gs/io/io.ts +546 -0
- package/gs/iter/godoc.txt +203 -0
- package/gs/iter/index.ts +1 -0
- package/gs/iter/iter.ts +117 -0
- package/gs/math/bits/index.ts +356 -0
- package/gs/math/godoc.txt +76 -0
- package/gs/path/index.ts +2 -0
- package/gs/path/match.ts +307 -0
- package/gs/path/path.ts +301 -0
- package/gs/runtime/godoc.txt +331 -0
- package/gs/runtime/index.ts +1 -0
- package/gs/runtime/runtime.ts +178 -0
- package/gs/slices/godoc.txt +44 -0
- package/gs/slices/index.ts +1 -0
- package/gs/slices/slices.ts +22 -0
- package/gs/strings/builder.test.ts +121 -0
- package/gs/strings/builder.ts +223 -0
- package/gs/strings/clone.test.ts +43 -0
- package/gs/strings/clone.ts +17 -0
- package/gs/strings/compare.test.ts +84 -0
- package/gs/strings/compare.ts +13 -0
- package/gs/strings/godoc.txt +66 -0
- package/gs/strings/index.ts +2 -0
- package/gs/strings/iter.test.ts +343 -0
- package/gs/strings/iter.ts +171 -0
- package/gs/strings/reader.test.ts +242 -0
- package/gs/strings/reader.ts +451 -0
- package/gs/strings/replace.test.ts +181 -0
- package/gs/strings/replace.ts +1310 -0
- package/gs/strings/search.test.ts +214 -0
- package/gs/strings/search.ts +213 -0
- package/gs/strings/strings.test.ts +477 -0
- package/gs/strings/strings.ts +510 -0
- package/gs/stringslite/godoc.txt +17 -0
- package/gs/stringslite/index.ts +1 -0
- package/gs/stringslite/strings.ts +82 -0
- package/gs/sync/godoc.txt +21 -0
- package/gs/sync/index.ts +1 -0
- package/gs/sync/sync.go +64 -0
- package/gs/sync/sync.ts +449 -0
- package/gs/time/godoc.txt +116 -0
- package/gs/time/index.ts +1 -0
- package/gs/time/time.ts +585 -0
- package/gs/unicode/godoc.txt +52 -0
- package/gs/unicode/index.ts +1 -0
- package/gs/unicode/unicode.go +38 -0
- package/gs/unicode/unicode.ts +418 -0
- package/gs/unicode/utf8/godoc.txt +22 -0
- package/gs/unicode/utf8/index.ts +2 -0
- package/gs/unicode/utf8/utf8.ts +227 -0
- package/gs/unsafe/godoc.txt +19 -0
- package/gs/unsafe/index.ts +1 -0
- package/gs/unsafe/unsafe.test.ts +68 -0
- package/gs/unsafe/unsafe.ts +77 -0
- package/package.json +4 -3
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { FS } from "./fs.js";
|
|
3
|
+
|
|
4
|
+
import * as io from "@goscript/io/index.js"
|
|
5
|
+
|
|
6
|
+
export type ReadFileFS = null | {
|
|
7
|
+
// ReadFile reads the named file and returns its contents.
|
|
8
|
+
// A successful call returns a nil error, not io.EOF.
|
|
9
|
+
// (Because ReadFile reads the whole file, the expected EOF
|
|
10
|
+
// from the final Read is not treated as an error to be reported.)
|
|
11
|
+
//
|
|
12
|
+
// The caller is permitted to modify the returned byte slice.
|
|
13
|
+
// This method should return a copy of the underlying data.
|
|
14
|
+
ReadFile(name: string): [Uint8Array, $.GoError]
|
|
15
|
+
} & FS
|
|
16
|
+
|
|
17
|
+
$.registerInterfaceType(
|
|
18
|
+
'ReadFileFS',
|
|
19
|
+
null, // Zero value for interface is null
|
|
20
|
+
[{ name: "ReadFile", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }]
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// ReadFile reads the named file from the file system fs and returns its contents.
|
|
24
|
+
// A successful call returns a nil error, not [io.EOF].
|
|
25
|
+
// (Because ReadFile reads the whole file, the expected EOF
|
|
26
|
+
// from the final Read is not treated as an error to be reported.)
|
|
27
|
+
//
|
|
28
|
+
// If fs implements [ReadFileFS], ReadFile calls fs.ReadFile.
|
|
29
|
+
// Otherwise ReadFile calls fs.Open and uses Read and Close
|
|
30
|
+
// on the returned [File].
|
|
31
|
+
export function ReadFile(fsys: FS, name: string): [Uint8Array, $.GoError] {
|
|
32
|
+
using __defer = new $.DisposableStack();
|
|
33
|
+
{
|
|
34
|
+
let { value: fsysTyped, ok: ok } = $.typeAssert<ReadFileFS>(fsys, 'ReadFileFS')
|
|
35
|
+
if (ok) {
|
|
36
|
+
return fsysTyped!.ReadFile(name)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let [file, err] = fsys!.Open(name)
|
|
41
|
+
if (err != null) {
|
|
42
|
+
return [new Uint8Array(0), err]
|
|
43
|
+
}
|
|
44
|
+
__defer.defer(() => {
|
|
45
|
+
file!.Close()
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let size: number = 0
|
|
49
|
+
{
|
|
50
|
+
let [info, err] = file!.Stat()
|
|
51
|
+
if (err == null) {
|
|
52
|
+
let size64 = info!.Size()
|
|
53
|
+
if (((size64 as number) as number) == size64) {
|
|
54
|
+
size = (size64 as number)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let data = new Uint8Array(0)
|
|
60
|
+
for (; ; ) {
|
|
61
|
+
if ($.len(data) >= $.cap(data)) {
|
|
62
|
+
// Grow the array by creating a new larger one
|
|
63
|
+
let newData = new Uint8Array($.len(data) * 2 + 1)
|
|
64
|
+
newData.set(data)
|
|
65
|
+
data = newData
|
|
66
|
+
}
|
|
67
|
+
let [n, err] = file!.Read(data.subarray($.len(data), $.cap(data)))
|
|
68
|
+
data = data.subarray(0, $.len(data) + n)
|
|
69
|
+
if (err != null) {
|
|
70
|
+
if (err == io.EOF) {
|
|
71
|
+
err = null
|
|
72
|
+
}
|
|
73
|
+
return [data, err]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
package/gs/io/fs/stat.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { FS, FileInfo } from "./fs.js";
|
|
3
|
+
|
|
4
|
+
export type StatFS = null | {
|
|
5
|
+
// Stat returns a FileInfo describing the file.
|
|
6
|
+
// If there is an error, it should be of type *PathError.
|
|
7
|
+
Stat(name: string): [FileInfo, $.GoError]
|
|
8
|
+
} & FS
|
|
9
|
+
|
|
10
|
+
$.registerInterfaceType(
|
|
11
|
+
'StatFS',
|
|
12
|
+
null, // Zero value for interface is null
|
|
13
|
+
[{ name: "Stat", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: "FileInfo" }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }]
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// Stat returns a [FileInfo] describing the named file from the file system.
|
|
17
|
+
//
|
|
18
|
+
// If fs implements [StatFS], Stat calls fs.Stat.
|
|
19
|
+
// Otherwise, Stat opens the [File] to stat it.
|
|
20
|
+
export function Stat(fsys: FS, name: string): [FileInfo, $.GoError] {
|
|
21
|
+
using __defer = new $.DisposableStack();
|
|
22
|
+
{
|
|
23
|
+
let { value: fsysTyped, ok: ok } = $.typeAssert<StatFS>(fsys, 'StatFS')
|
|
24
|
+
if (ok) {
|
|
25
|
+
return fsysTyped!.Stat(name)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let [file, err] = fsys!.Open(name)
|
|
30
|
+
if (err != null) {
|
|
31
|
+
return [null, err]
|
|
32
|
+
}
|
|
33
|
+
__defer.defer(() => {
|
|
34
|
+
file!.Close()
|
|
35
|
+
});
|
|
36
|
+
return file!.Stat()
|
|
37
|
+
}
|
|
38
|
+
|
package/gs/io/fs/sub.ts
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { ValidPath, FS, PathError, ErrInvalid, File, DirEntry } from "./fs.js";
|
|
3
|
+
import { ReadDir } from "./readdir.js";
|
|
4
|
+
import { ReadFile } from "./readfile.js";
|
|
5
|
+
import { Glob } from "./glob.js";
|
|
6
|
+
|
|
7
|
+
import * as errors from "@goscript/errors/index.js"
|
|
8
|
+
|
|
9
|
+
import * as path from "@goscript/path/index.js"
|
|
10
|
+
|
|
11
|
+
export type SubFS = null | {
|
|
12
|
+
// Sub returns an FS corresponding to the subtree rooted at dir.
|
|
13
|
+
Sub(dir: string): [FS, $.GoError]
|
|
14
|
+
} & FS
|
|
15
|
+
|
|
16
|
+
$.registerInterfaceType(
|
|
17
|
+
'SubFS',
|
|
18
|
+
null, // Zero value for interface is null
|
|
19
|
+
[{ name: "Sub", args: [{ name: "dir", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: "FS" }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }]
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// Sub returns an [FS] corresponding to the subtree rooted at fsys's dir.
|
|
23
|
+
//
|
|
24
|
+
// If dir is ".", Sub returns fsys unchanged.
|
|
25
|
+
// Otherwise, if fs implements [SubFS], Sub returns fsys.Sub(dir).
|
|
26
|
+
// Otherwise, Sub returns a new [FS] implementation sub that,
|
|
27
|
+
// in effect, implements sub.Open(name) as fsys.Open(path.Join(dir, name)).
|
|
28
|
+
// The implementation also translates calls to ReadDir, ReadFile, and Glob appropriately.
|
|
29
|
+
//
|
|
30
|
+
// Note that Sub(os.DirFS("/"), "prefix") is equivalent to os.DirFS("/prefix")
|
|
31
|
+
// and that neither of them guarantees to avoid operating system
|
|
32
|
+
// accesses outside "/prefix", because the implementation of [os.DirFS]
|
|
33
|
+
// does not check for symbolic links inside "/prefix" that point to
|
|
34
|
+
// other directories. That is, [os.DirFS] is not a general substitute for a
|
|
35
|
+
// chroot-style security mechanism, and Sub does not change that fact.
|
|
36
|
+
export function Sub(fsys: FS, dir: string): [FS, $.GoError] {
|
|
37
|
+
if (!ValidPath(dir)) {
|
|
38
|
+
return [null, new PathError({Err: ErrInvalid, Op: "sub", Path: dir})]
|
|
39
|
+
}
|
|
40
|
+
if (dir == ".") {
|
|
41
|
+
return [fsys, null]
|
|
42
|
+
}
|
|
43
|
+
{
|
|
44
|
+
let { value: fsysTyped, ok: ok } = $.typeAssert<SubFS>(fsys, 'SubFS')
|
|
45
|
+
if (ok) {
|
|
46
|
+
return fsysTyped!.Sub(dir)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [new subFS({}), null]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class subFS {
|
|
53
|
+
public get fsys(): FS {
|
|
54
|
+
return this._fields.fsys.value
|
|
55
|
+
}
|
|
56
|
+
public set fsys(value: FS) {
|
|
57
|
+
this._fields.fsys.value = value
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public get dir(): string {
|
|
61
|
+
return this._fields.dir.value
|
|
62
|
+
}
|
|
63
|
+
public set dir(value: string) {
|
|
64
|
+
this._fields.dir.value = value
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public _fields: {
|
|
68
|
+
fsys: $.VarRef<FS>;
|
|
69
|
+
dir: $.VarRef<string>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
constructor(init?: Partial<{dir?: string, fsys?: FS}>) {
|
|
73
|
+
this._fields = {
|
|
74
|
+
fsys: $.varRef(init?.fsys ?? null),
|
|
75
|
+
dir: $.varRef(init?.dir ?? "")
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public clone(): subFS {
|
|
80
|
+
const cloned = new subFS()
|
|
81
|
+
cloned._fields = {
|
|
82
|
+
fsys: $.varRef(this._fields.fsys.value),
|
|
83
|
+
dir: $.varRef(this._fields.dir.value)
|
|
84
|
+
}
|
|
85
|
+
return cloned
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// fullName maps name to the fully-qualified name dir/name.
|
|
89
|
+
public fullName(op: string, name: string): [string, $.GoError] {
|
|
90
|
+
const f = this
|
|
91
|
+
if (!ValidPath(name)) {
|
|
92
|
+
return ["", new PathError({Err: ErrInvalid, Op: op, Path: name})]
|
|
93
|
+
}
|
|
94
|
+
return [path.Join(f!.dir, name), null]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// shorten maps name, which should start with f.dir, back to the suffix after f.dir.
|
|
98
|
+
public shorten(name: string): [string, boolean] {
|
|
99
|
+
const f = this
|
|
100
|
+
if (name == f!.dir) {
|
|
101
|
+
return [".", true]
|
|
102
|
+
}
|
|
103
|
+
if ($.len(name) >= $.len(f!.dir) + 2 && $.indexString(name, $.len(f!.dir)) == 47 && $.sliceString(name, undefined, $.len(f!.dir)) == f!.dir) {
|
|
104
|
+
return [$.sliceString(name, $.len(f!.dir) + 1, undefined), true]
|
|
105
|
+
}
|
|
106
|
+
return ["", false]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// fixErr shortens any reported names in PathErrors by stripping f.dir.
|
|
110
|
+
public fixErr(err: $.GoError): $.GoError {
|
|
111
|
+
const f = this
|
|
112
|
+
{
|
|
113
|
+
let { value: e, ok: ok } = $.typeAssert<PathError | null>(err, {kind: $.TypeKind.Pointer, elemType: 'PathError'})
|
|
114
|
+
if (ok) {
|
|
115
|
+
{
|
|
116
|
+
let [short, ok] = f!.shorten(e!.Path)
|
|
117
|
+
if (ok) {
|
|
118
|
+
e!.Path = short
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return err
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public Open(name: string): [File, $.GoError] {
|
|
127
|
+
const f = this
|
|
128
|
+
let [full, err] = f!.fullName("open", name)
|
|
129
|
+
if (err != null) {
|
|
130
|
+
return [null, err]
|
|
131
|
+
}
|
|
132
|
+
let file: File
|
|
133
|
+
[file, err] = f!.fsys!.Open(full)
|
|
134
|
+
return [file, f!.fixErr(err)]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public ReadDir(name: string): [$.Slice<DirEntry>, $.GoError] {
|
|
138
|
+
const f = this
|
|
139
|
+
let [full, err] = f!.fullName("read", name)
|
|
140
|
+
if (err != null) {
|
|
141
|
+
return [null, err]
|
|
142
|
+
}
|
|
143
|
+
let dir: $.Slice<DirEntry>
|
|
144
|
+
[dir, err] = ReadDir(f!.fsys, full)
|
|
145
|
+
return [dir, f!.fixErr(err)]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public ReadFile(name: string): [Uint8Array, $.GoError] {
|
|
149
|
+
const f = this
|
|
150
|
+
let [full, err] = f!.fullName("read", name)
|
|
151
|
+
if (err != null) {
|
|
152
|
+
return [new Uint8Array(0), err]
|
|
153
|
+
}
|
|
154
|
+
let data: Uint8Array
|
|
155
|
+
[data, err] = ReadFile(f!.fsys, full)
|
|
156
|
+
return [data, f!.fixErr(err)]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public Glob(pattern: string): [$.Slice<string>, $.GoError] {
|
|
160
|
+
const f = this
|
|
161
|
+
{
|
|
162
|
+
let [, err] = path.Match(pattern, "")
|
|
163
|
+
if (err != null) {
|
|
164
|
+
return [null, err]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (pattern == ".") {
|
|
168
|
+
return [$.arrayToSlice<string>(["."]), null]
|
|
169
|
+
}
|
|
170
|
+
let full = f!.dir + "/" + pattern
|
|
171
|
+
let [list, err] = Glob(f!.fsys, full)
|
|
172
|
+
for (let i = 0; i < $.len(list); i++) {
|
|
173
|
+
const name = list![i]
|
|
174
|
+
{
|
|
175
|
+
let [shortName, ok] = f!.shorten(name)
|
|
176
|
+
|
|
177
|
+
// can't use fmt in this package
|
|
178
|
+
if (!ok) {
|
|
179
|
+
return [null, errors.New("invalid result from inner fsys Glob: " + shortName + " not in " + f!.dir)]
|
|
180
|
+
}
|
|
181
|
+
list![i] = shortName
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return [list, f!.fixErr(err)]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public Sub(dir: string): [FS, $.GoError] {
|
|
188
|
+
const f = this
|
|
189
|
+
if (dir == ".") {
|
|
190
|
+
return [f, null]
|
|
191
|
+
}
|
|
192
|
+
let [full, err] = f!.fullName("sub", dir)
|
|
193
|
+
if (err != null) {
|
|
194
|
+
return [null, err]
|
|
195
|
+
}
|
|
196
|
+
return [new subFS({}), null]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Register this type with the runtime type system
|
|
200
|
+
static __typeInfo = $.registerStructType(
|
|
201
|
+
'subFS',
|
|
202
|
+
new subFS(),
|
|
203
|
+
[{ name: "fullName", args: [{ name: "op", type: { kind: $.TypeKind.Basic, name: "string" } }, { name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "shorten", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }, { type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "fixErr", args: [{ name: "err", type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Open", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: "File" }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadDir", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: "DirEntry" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadFile", args: [{ name: "name", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Glob", args: [{ name: "pattern", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "string" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Sub", args: [{ name: "dir", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: "FS" }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }],
|
|
204
|
+
subFS,
|
|
205
|
+
{"fsys": "FS", "dir": { kind: $.TypeKind.Basic, name: "string" }}
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
package/gs/io/fs/walk.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as $ from "@goscript/builtin/builtin.js";
|
|
2
|
+
import { FileInfoToDirEntry, ReadDir } from "./readdir.js";
|
|
3
|
+
import { Stat } from "./stat.js";
|
|
4
|
+
import { FS, DirEntry } from "./fs.js";
|
|
5
|
+
|
|
6
|
+
import * as errors from "@goscript/errors/index.js"
|
|
7
|
+
|
|
8
|
+
import * as path from "@goscript/path/index.js"
|
|
9
|
+
|
|
10
|
+
export let SkipDir: $.GoError = errors.New("skip this directory")
|
|
11
|
+
|
|
12
|
+
export let SkipAll: $.GoError = errors.New("skip everything and stop the walk")
|
|
13
|
+
|
|
14
|
+
export type WalkDirFunc = ((path: string, d: DirEntry, err: $.GoError) => $.GoError) | null;
|
|
15
|
+
|
|
16
|
+
// walkDir recursively descends path, calling walkDirFn.
|
|
17
|
+
export function walkDir(fsys: FS, name: string, d: DirEntry, walkDirFn: WalkDirFunc): $.GoError {
|
|
18
|
+
|
|
19
|
+
// Successfully skipped directory.
|
|
20
|
+
{
|
|
21
|
+
let err = walkDirFn!(name, d, null)
|
|
22
|
+
if (err != null || !d!.IsDir()) {
|
|
23
|
+
|
|
24
|
+
// Successfully skipped directory.
|
|
25
|
+
if (err == SkipDir && d!.IsDir()) {
|
|
26
|
+
// Successfully skipped directory.
|
|
27
|
+
err = null
|
|
28
|
+
}
|
|
29
|
+
return err
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let [dirs, err] = ReadDir(fsys, name)
|
|
34
|
+
|
|
35
|
+
// Second call, to report ReadDir error.
|
|
36
|
+
if (err != null) {
|
|
37
|
+
// Second call, to report ReadDir error.
|
|
38
|
+
err = walkDirFn!(name, d, err)
|
|
39
|
+
if (err != null) {
|
|
40
|
+
if (err == SkipDir && d!.IsDir()) {
|
|
41
|
+
err = null
|
|
42
|
+
}
|
|
43
|
+
return err
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for (let _i = 0; _i < $.len(dirs); _i++) {
|
|
48
|
+
const d1 = dirs![_i]
|
|
49
|
+
{
|
|
50
|
+
let name1 = path.Join(name, d1!.Name())
|
|
51
|
+
{
|
|
52
|
+
let err = walkDir(fsys, name1, d1, walkDirFn)
|
|
53
|
+
if (err != null) {
|
|
54
|
+
if (err == SkipDir) {
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
return err
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// WalkDir walks the file tree rooted at root, calling fn for each file or
|
|
66
|
+
// directory in the tree, including root.
|
|
67
|
+
//
|
|
68
|
+
// All errors that arise visiting files and directories are filtered by fn:
|
|
69
|
+
// see the [fs.WalkDirFunc] documentation for details.
|
|
70
|
+
//
|
|
71
|
+
// The files are walked in lexical order, which makes the output deterministic
|
|
72
|
+
// but requires WalkDir to read an entire directory into memory before proceeding
|
|
73
|
+
// to walk that directory.
|
|
74
|
+
//
|
|
75
|
+
// WalkDir does not follow symbolic links found in directories,
|
|
76
|
+
// but if root itself is a symbolic link, its target will be walked.
|
|
77
|
+
export function WalkDir(fsys: FS, root: string, fn: WalkDirFunc): $.GoError {
|
|
78
|
+
let [info, err] = Stat(fsys, root)
|
|
79
|
+
if (err != null) {
|
|
80
|
+
err = fn!(root, null, err)
|
|
81
|
+
} else {
|
|
82
|
+
err = walkDir(fsys, root, FileInfoToDirEntry(info), fn)
|
|
83
|
+
}
|
|
84
|
+
if (err == SkipDir || err == SkipAll) {
|
|
85
|
+
return null
|
|
86
|
+
}
|
|
87
|
+
return err
|
|
88
|
+
}
|
|
89
|
+
|
package/gs/io/godoc.txt
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package io // import "io"
|
|
2
|
+
|
|
3
|
+
Package io provides basic interfaces to I/O primitives. Its primary job is to
|
|
4
|
+
wrap existing implementations of such primitives, such as those in package os,
|
|
5
|
+
into shared public interfaces that abstract the functionality, plus some other
|
|
6
|
+
related primitives.
|
|
7
|
+
|
|
8
|
+
Because these interfaces and primitives wrap lower-level operations with various
|
|
9
|
+
implementations, unless otherwise informed clients should not assume they are
|
|
10
|
+
safe for parallel execution.
|
|
11
|
+
|
|
12
|
+
const SeekStart = 0 ...
|
|
13
|
+
var EOF = errors.New("EOF")
|
|
14
|
+
var ErrClosedPipe = errors.New("io: read/write on closed pipe")
|
|
15
|
+
var ErrNoProgress = errors.New("multiple Read calls return no data or error")
|
|
16
|
+
var ErrShortBuffer = errors.New("short buffer")
|
|
17
|
+
var ErrShortWrite = errors.New("short write")
|
|
18
|
+
var ErrUnexpectedEOF = errors.New("unexpected EOF")
|
|
19
|
+
func Copy(dst Writer, src Reader) (written int64, err error)
|
|
20
|
+
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
|
|
21
|
+
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
|
|
22
|
+
func Pipe() (*PipeReader, *PipeWriter)
|
|
23
|
+
func ReadAll(r Reader) ([]byte, error)
|
|
24
|
+
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
|
|
25
|
+
func ReadFull(r Reader, buf []byte) (n int, err error)
|
|
26
|
+
func WriteString(w Writer, s string) (n int, err error)
|
|
27
|
+
type ByteReader interface{ ... }
|
|
28
|
+
type ByteScanner interface{ ... }
|
|
29
|
+
type ByteWriter interface{ ... }
|
|
30
|
+
type Closer interface{ ... }
|
|
31
|
+
type LimitedReader struct{ ... }
|
|
32
|
+
type OffsetWriter struct{ ... }
|
|
33
|
+
func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter
|
|
34
|
+
type PipeReader struct{ ... }
|
|
35
|
+
type PipeWriter struct{ ... }
|
|
36
|
+
type ReadCloser interface{ ... }
|
|
37
|
+
func NopCloser(r Reader) ReadCloser
|
|
38
|
+
type ReadSeekCloser interface{ ... }
|
|
39
|
+
type ReadSeeker interface{ ... }
|
|
40
|
+
type ReadWriteCloser interface{ ... }
|
|
41
|
+
type ReadWriteSeeker interface{ ... }
|
|
42
|
+
type ReadWriter interface{ ... }
|
|
43
|
+
type Reader interface{ ... }
|
|
44
|
+
func LimitReader(r Reader, n int64) Reader
|
|
45
|
+
func MultiReader(readers ...Reader) Reader
|
|
46
|
+
func TeeReader(r Reader, w Writer) Reader
|
|
47
|
+
type ReaderAt interface{ ... }
|
|
48
|
+
type ReaderFrom interface{ ... }
|
|
49
|
+
type RuneReader interface{ ... }
|
|
50
|
+
type RuneScanner interface{ ... }
|
|
51
|
+
type SectionReader struct{ ... }
|
|
52
|
+
func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
|
|
53
|
+
type Seeker interface{ ... }
|
|
54
|
+
type StringWriter interface{ ... }
|
|
55
|
+
type WriteCloser interface{ ... }
|
|
56
|
+
type WriteSeeker interface{ ... }
|
|
57
|
+
type Writer interface{ ... }
|
|
58
|
+
var Discard Writer = discard{}
|
|
59
|
+
func MultiWriter(writers ...Writer) Writer
|
|
60
|
+
type WriterAt interface{ ... }
|
|
61
|
+
type WriterTo interface{ ... }
|
package/gs/io/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './io.js'
|
package/gs/io/io.go
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
package io
|
|
2
|
+
|
|
3
|
+
import "github.com/aperturerobotics/goscript/compiler"
|
|
4
|
+
|
|
5
|
+
// Metadata for io package functions
|
|
6
|
+
// This defines which functions/methods are async for the compiler analysis
|
|
7
|
+
|
|
8
|
+
// Most io operations are synchronous in our implementation
|
|
9
|
+
// since we're dealing with in-memory operations and simple transformations
|
|
10
|
+
|
|
11
|
+
// Copy functions - these could potentially be async if dealing with large data
|
|
12
|
+
// but for simplicity, we'll keep them sync for now
|
|
13
|
+
var (
|
|
14
|
+
CopyInfo = compiler.FunctionInfo{IsAsync: false}
|
|
15
|
+
CopyBufferInfo = compiler.FunctionInfo{IsAsync: false}
|
|
16
|
+
CopyNInfo = compiler.FunctionInfo{IsAsync: false}
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
// Read functions - sync since they're immediate operations
|
|
20
|
+
var (
|
|
21
|
+
ReadAllInfo = compiler.FunctionInfo{IsAsync: false}
|
|
22
|
+
ReadAtLeastInfo = compiler.FunctionInfo{IsAsync: false}
|
|
23
|
+
ReadFullInfo = compiler.FunctionInfo{IsAsync: false}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
// Write functions - sync
|
|
27
|
+
var WriteStringInfo = compiler.FunctionInfo{IsAsync: false}
|
|
28
|
+
|
|
29
|
+
// Utility functions - sync
|
|
30
|
+
var (
|
|
31
|
+
LimitReaderInfo = compiler.FunctionInfo{IsAsync: false}
|
|
32
|
+
MultiReaderInfo = compiler.FunctionInfo{IsAsync: false}
|
|
33
|
+
MultiWriterInfo = compiler.FunctionInfo{IsAsync: false}
|
|
34
|
+
TeeReaderInfo = compiler.FunctionInfo{IsAsync: false}
|
|
35
|
+
NopCloserInfo = compiler.FunctionInfo{IsAsync: false}
|
|
36
|
+
NewSectionReaderInfo = compiler.FunctionInfo{IsAsync: false}
|
|
37
|
+
NewOffsetWriterInfo = compiler.FunctionInfo{IsAsync: false}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
// Interface methods - sync for basic operations
|
|
41
|
+
// Reader methods
|
|
42
|
+
var ReaderReadInfo = compiler.FunctionInfo{IsAsync: false}
|
|
43
|
+
|
|
44
|
+
// Writer methods
|
|
45
|
+
var WriterWriteInfo = compiler.FunctionInfo{IsAsync: false}
|
|
46
|
+
|
|
47
|
+
// Closer methods
|
|
48
|
+
var CloserCloseInfo = compiler.FunctionInfo{IsAsync: false}
|
|
49
|
+
|
|
50
|
+
// Seeker methods
|
|
51
|
+
var SeekerSeekInfo = compiler.FunctionInfo{IsAsync: false}
|
|
52
|
+
|
|
53
|
+
// ReaderAt methods
|
|
54
|
+
var ReaderAtReadAtInfo = compiler.FunctionInfo{IsAsync: false}
|
|
55
|
+
|
|
56
|
+
// WriterAt methods
|
|
57
|
+
var WriterAtWriteAtInfo = compiler.FunctionInfo{IsAsync: false}
|
|
58
|
+
|
|
59
|
+
// LimitedReader methods
|
|
60
|
+
var LimitedReaderReadInfo = compiler.FunctionInfo{IsAsync: false}
|
|
61
|
+
|
|
62
|
+
// SectionReader methods
|
|
63
|
+
var (
|
|
64
|
+
SectionReaderReadInfo = compiler.FunctionInfo{IsAsync: false}
|
|
65
|
+
SectionReaderSeekInfo = compiler.FunctionInfo{IsAsync: false}
|
|
66
|
+
SectionReaderReadAtInfo = compiler.FunctionInfo{IsAsync: false}
|
|
67
|
+
SectionReaderSizeInfo = compiler.FunctionInfo{IsAsync: false}
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
// OffsetWriter methods
|
|
71
|
+
var (
|
|
72
|
+
OffsetWriterWriteInfo = compiler.FunctionInfo{IsAsync: false}
|
|
73
|
+
OffsetWriterWriteAtInfo = compiler.FunctionInfo{IsAsync: false}
|
|
74
|
+
OffsetWriterSeekInfo = compiler.FunctionInfo{IsAsync: false}
|
|
75
|
+
)
|