firefly-compiler 0.4.50 → 0.4.52
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/.hintrc +4 -4
- package/.vscode/settings.json +4 -4
- package/bin/Release.ff +153 -155
- package/bin/firefly.mjs +1 -1
- package/compiler/Builder.ff +257 -257
- package/compiler/Compiler.ff +227 -227
- package/compiler/Dependencies.ff +186 -186
- package/compiler/DependencyLock.ff +17 -17
- package/compiler/JsEmitter.ff +946 -946
- package/compiler/LspHook.ff +202 -202
- package/compiler/ModuleCache.ff +178 -178
- package/compiler/Workspace.ff +88 -88
- package/core/.firefly/include/package-lock.json +394 -394
- package/core/.firefly/include/package.json +5 -5
- package/core/.firefly/include/prepare.sh +1 -1
- package/core/.firefly/package.ff +2 -2
- package/core/Array.ff +265 -265
- package/core/Atomic.ff +64 -64
- package/core/Box.ff +7 -7
- package/core/BrowserSystem.ff +40 -40
- package/core/BuildSystem.ff +148 -148
- package/core/Crypto.ff +96 -96
- package/core/Equal.ff +36 -36
- package/core/HttpClient.ff +87 -87
- package/core/JsSystem.ff +69 -69
- package/core/Json.ff +434 -434
- package/core/List.ff +486 -486
- package/core/Lock.ff +144 -144
- package/core/NodeSystem.ff +195 -189
- package/core/Ordering.ff +161 -161
- package/core/Path.ff +401 -401
- package/core/Random.ff +134 -134
- package/core/RbMap.ff +216 -216
- package/core/Show.ff +43 -43
- package/core/SourceLocation.ff +68 -68
- package/core/Task.ff +141 -141
- package/experimental/benchmarks/ListGrab.ff +23 -23
- package/experimental/benchmarks/ListGrab.java +55 -55
- package/experimental/benchmarks/Pyrotek45.ff +30 -30
- package/experimental/benchmarks/Pyrotek45.java +64 -64
- package/experimental/bidirectional/Bidi.ff +88 -88
- package/experimental/random/Index.ff +53 -53
- package/experimental/random/Process.ff +120 -120
- package/experimental/random/Scrape.ff +51 -51
- package/experimental/random/Symbols.ff +73 -73
- package/experimental/random/Tensor.ff +52 -52
- package/experimental/random/Units.ff +36 -36
- package/experimental/s3/S3TestAuthorizationHeader.ff +38 -38
- package/experimental/s3/S3TestPut.ff +15 -15
- package/experimental/tests/TestJson.ff +26 -26
- package/firefly.sh +0 -0
- package/fireflysite/Main.ff +13 -13
- package/lsp/.firefly/package.ff +1 -1
- package/lsp/CompletionHandler.ff +808 -808
- package/lsp/Handler.ff +714 -714
- package/lsp/HoverHandler.ff +79 -79
- package/lsp/LanguageServer.ff +272 -272
- package/lsp/SignatureHelpHandler.ff +55 -55
- package/lsp/SymbolHandler.ff +181 -181
- package/lsp/TestReferences.ff +16 -16
- package/lsp/TestReferencesCase.ff +7 -7
- package/lsp/stderr.txt +1 -1
- package/lsp/stdin.txt +10 -10
- package/lsp/stdout.txt +40 -40
- package/lux/.firefly/package.ff +1 -1
- package/lux/Css.ff +648 -648
- package/lux/CssTest.ff +48 -48
- package/lux/Lux.ff +487 -487
- package/lux/LuxEvent.ff +116 -116
- package/lux/Main.ff +128 -128
- package/lux/Main2.ff +144 -144
- package/output/js/ff/compiler/Builder.mjs +43 -43
- package/output/js/ff/compiler/Dependencies.mjs +3 -3
- package/output/js/ff/core/Array.mjs +59 -59
- package/output/js/ff/core/Atomic.mjs +36 -36
- package/output/js/ff/core/BrowserSystem.mjs +11 -11
- package/output/js/ff/core/BuildSystem.mjs +30 -30
- package/output/js/ff/core/Crypto.mjs +40 -40
- package/output/js/ff/core/HttpClient.mjs +24 -24
- package/output/js/ff/core/Json.mjs +147 -147
- package/output/js/ff/core/List.mjs +50 -50
- package/output/js/ff/core/Lock.mjs +97 -97
- package/output/js/ff/core/NodeSystem.mjs +83 -77
- package/output/js/ff/core/Ordering.mjs +8 -8
- package/output/js/ff/core/Path.mjs +231 -231
- package/output/js/ff/core/Random.mjs +56 -56
- package/output/js/ff/core/Task.mjs +31 -31
- package/package.json +1 -1
- package/rpc/.firefly/package.ff +1 -1
- package/rpc/Rpc.ff +69 -69
- package/s3/.firefly/package.ff +1 -1
- package/s3/S3.ff +90 -93
- package/unsafejs/UnsafeJs.ff +19 -19
- package/vscode/LICENSE.txt +21 -21
- package/vscode/Prepublish.ff +15 -15
- package/vscode/README.md +16 -16
- package/vscode/client/package.json +22 -22
- package/vscode/client/src/extension.ts +104 -104
- package/vscode/icons/firefly-icon.svg +10 -10
- package/vscode/language-configuration.json +61 -61
- package/vscode/package-lock.json +3623 -3623
- package/vscode/package.json +1 -1
- package/vscode/snippets.json +241 -241
- package/webserver/.firefly/include/package-lock.json +16 -16
- package/webserver/.firefly/include/package.json +5 -5
- package/webserver/.firefly/package.ff +2 -2
- package/webserver/WebServer.ff +685 -685
- package/websocket/.firefly/package.ff +1 -1
- package/websocket/WebSocket.ff +131 -131
package/core/Box.ff
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class Box[T](mutable value: T)
|
|
2
|
-
|
|
3
|
-
extend self[T]: Box[T] {
|
|
4
|
-
modify(body: T => T): Unit {
|
|
5
|
-
self.value = body(self.value)
|
|
6
|
-
}
|
|
7
|
-
}
|
|
1
|
+
class Box[T](mutable value: T)
|
|
2
|
+
|
|
3
|
+
extend self[T]: Box[T] {
|
|
4
|
+
modify(body: T => T): Unit {
|
|
5
|
+
self.value = body(self.value)
|
|
6
|
+
}
|
|
7
|
+
}
|
package/core/BrowserSystem.ff
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
capability BrowserSystem {}
|
|
2
|
-
|
|
3
|
-
extend self: BrowserSystem {
|
|
4
|
-
|
|
5
|
-
httpClient(): HttpClient
|
|
6
|
-
target js async "return null"
|
|
7
|
-
|
|
8
|
-
mainTask(): Task
|
|
9
|
-
target js async "return self_.task_"
|
|
10
|
-
|
|
11
|
-
crypto(): Crypto
|
|
12
|
-
target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
|
|
13
|
-
|
|
14
|
-
js(): JsSystem
|
|
15
|
-
target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
|
|
16
|
-
|
|
17
|
-
url(): String
|
|
18
|
-
target js async """
|
|
19
|
-
return location.href;
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
urlPath(): String
|
|
23
|
-
target js async """
|
|
24
|
-
return location.pathname;
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
urlQuery(name: String): Option[String]
|
|
28
|
-
target js async """
|
|
29
|
-
const param = new URLSearchParams(location.search).get(name_)
|
|
30
|
-
if(param == null) return ff_core_Option.None();
|
|
31
|
-
return ff_core_Option.Some(param);
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
urlFragment(): Option[String]
|
|
35
|
-
target js async """
|
|
36
|
-
if(!location.hash.startsWith('#')) return ff_core_Option.None();
|
|
37
|
-
return ff_core_Option.Some(location.hash.slice(1));
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
}
|
|
1
|
+
capability BrowserSystem {}
|
|
2
|
+
|
|
3
|
+
extend self: BrowserSystem {
|
|
4
|
+
|
|
5
|
+
httpClient(): HttpClient
|
|
6
|
+
target js async "return null"
|
|
7
|
+
|
|
8
|
+
mainTask(): Task
|
|
9
|
+
target js async "return self_.task_"
|
|
10
|
+
|
|
11
|
+
crypto(): Crypto
|
|
12
|
+
target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
|
|
13
|
+
|
|
14
|
+
js(): JsSystem
|
|
15
|
+
target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
|
|
16
|
+
|
|
17
|
+
url(): String
|
|
18
|
+
target js async """
|
|
19
|
+
return location.href;
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
urlPath(): String
|
|
23
|
+
target js async """
|
|
24
|
+
return location.pathname;
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
urlQuery(name: String): Option[String]
|
|
28
|
+
target js async """
|
|
29
|
+
const param = new URLSearchParams(location.search).get(name_)
|
|
30
|
+
if(param == null) return ff_core_Option.None();
|
|
31
|
+
return ff_core_Option.Some(param);
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
urlFragment(): Option[String]
|
|
35
|
+
target js async """
|
|
36
|
+
if(!location.hash.startsWith('#')) return ff_core_Option.None();
|
|
37
|
+
return ff_core_Option.Some(location.hash.slice(1));
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
}
|
package/core/BuildSystem.ff
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
capability BuildSystem {}
|
|
2
|
-
capability BrowserCode(packageGroup: String, packageName: String, mainFile: Path, assetSystem: AssetSystem)
|
|
3
|
-
capability BrowserBundle(assetSystem: AssetSystem)
|
|
4
|
-
|
|
5
|
-
extend self: BuildSystem {
|
|
6
|
-
|
|
7
|
-
compileForBrowser(mainFile: String): BrowserCode {
|
|
8
|
-
// TODO: Check that the mainFile is in the current package directory
|
|
9
|
-
internalCompile(self, internalPath(self, mainFile), "browser")
|
|
10
|
-
let streams = internalListDirectory(internalPath(self, ".firefly/output/browser"))
|
|
11
|
-
let mainPackagePair = internalMainPackagePair(self)
|
|
12
|
-
BrowserCode(
|
|
13
|
-
packageGroup = mainPackagePair.first
|
|
14
|
-
packageName = mainPackagePair.second
|
|
15
|
-
mainFile = internalPath(self, mainFile)
|
|
16
|
-
assetSystem = AssetSystem(streams.toMap())
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
buildMode(): Bool
|
|
21
|
-
target node async "return !!self_.buildMode_"
|
|
22
|
-
|
|
23
|
-
setAssets(assetSystem: AssetSystem): Unit
|
|
24
|
-
target node async "self_.assets_ = assetSystem_"
|
|
25
|
-
|
|
26
|
-
packageAssets(): AssetSystem {
|
|
27
|
-
let streams = internalListDirectory(internalPath(self, "."))
|
|
28
|
-
AssetSystem(streams.toMap())
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
dependencyAssets(user: String, package: String): AssetSystem {
|
|
32
|
-
panic("dependencyAssets not yet implemented")
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
arguments(): List[String]
|
|
36
|
-
target node async "return self_.array_"
|
|
37
|
-
|
|
38
|
-
mainTask(): Task
|
|
39
|
-
target js async "return self_.task_"
|
|
40
|
-
|
|
41
|
-
crypto(): Crypto
|
|
42
|
-
target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
extend self: BrowserCode {
|
|
47
|
-
|
|
48
|
-
assets(): AssetSystem {
|
|
49
|
-
self.assetSystem
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
bundle(minify: Bool = True, sourceMap: Bool = False): BrowserBundle {
|
|
53
|
-
let prefix = ".firefly/output/browser"
|
|
54
|
-
let mainJsBaseFile = self.mainFile.base().removeLast(".ff").grab() + ".mjs"
|
|
55
|
-
let mainJsFile = prefix + "/" + self.packageGroup + "/" + self.packageName + "/" + mainJsBaseFile
|
|
56
|
-
let mainDirectory = self.mainFile.parent().grab()
|
|
57
|
-
let file = prefix + "/Main.bundle.js"
|
|
58
|
-
internalCallEsBuild(self, mainJsFile = mainJsFile, outputPath = file, minify = minify, sourceMap = sourceMap)
|
|
59
|
-
let assets = AssetSystem([
|
|
60
|
-
Pair(file.dropFirst(prefix.size()), {mainDirectory.path(file).readStream()})
|
|
61
|
-
...if(sourceMap) {[
|
|
62
|
-
Pair(file.dropFirst(prefix.size()) + ".map", {mainDirectory.path(file + ".map").readStream()})
|
|
63
|
-
]} else {[]}
|
|
64
|
-
].toMap())
|
|
65
|
-
BrowserBundle(assets)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
extend self: BrowserBundle {
|
|
71
|
-
|
|
72
|
-
assets(): AssetSystem {
|
|
73
|
-
self.assetSystem
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
internalCallEsBuild(
|
|
80
|
-
self: BrowserCode
|
|
81
|
-
mainJsFile: String
|
|
82
|
-
outputPath: String
|
|
83
|
-
minify: Bool
|
|
84
|
-
sourceMap: Bool
|
|
85
|
-
): Unit
|
|
86
|
-
target node async """
|
|
87
|
-
import * as esbuild from 'esbuild'
|
|
88
|
-
return await esbuild.build({
|
|
89
|
-
entryPoints: [mainJsFile_],
|
|
90
|
-
bundle: true,
|
|
91
|
-
minify: minify_,
|
|
92
|
-
sourcemap: sourceMap_,
|
|
93
|
-
platform: 'browser',
|
|
94
|
-
target: 'es6',
|
|
95
|
-
external: ['../../../node_modules/*'], // TODO
|
|
96
|
-
outfile: outputPath_
|
|
97
|
-
})
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
internalNodeCallEsBuild(
|
|
101
|
-
self: NodeSystem
|
|
102
|
-
mainJsFile: String
|
|
103
|
-
outputPath: String
|
|
104
|
-
minify: Bool
|
|
105
|
-
): Unit
|
|
106
|
-
target node async """
|
|
107
|
-
import * as esbuild from 'esbuild'
|
|
108
|
-
return await esbuild.build({
|
|
109
|
-
entryPoints: [mainJsFile_],
|
|
110
|
-
bundle: true,
|
|
111
|
-
minify: minify_,
|
|
112
|
-
sourcemap: true,
|
|
113
|
-
platform: 'node',
|
|
114
|
-
target: 'es6',
|
|
115
|
-
external: ['../../../node_modules/*'], // TODO
|
|
116
|
-
outfile: outputPath_
|
|
117
|
-
})
|
|
118
|
-
"""
|
|
119
|
-
|
|
120
|
-
internalListDirectory(path: Path): List[Pair[String, () => Stream[Buffer]]] {
|
|
121
|
-
function go(currentPath: Path): Stream[Path] {
|
|
122
|
-
currentPath.entries().flatMap {file =>
|
|
123
|
-
if(file.isDirectory()) {
|
|
124
|
-
go(file.path())
|
|
125
|
-
} else {
|
|
126
|
-
[file.path()].toStream()
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
go(path).map {file =>
|
|
131
|
-
Pair("/" + file.relativeTo(path).replace("\\", "/"), {file.readStream()})
|
|
132
|
-
}.toList()
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
internalPath(buildSystem: BuildSystem, absoluteOrRelative: String): Path
|
|
136
|
-
target node async """
|
|
137
|
-
return absoluteOrRelative_
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
internalCompile(buildSystem: BuildSystem, mainFile: Path, target: String): Unit
|
|
141
|
-
target node async """
|
|
142
|
-
return await $firefly_compiler.buildViaBuildSystem_$(buildSystem_, buildSystem_.fireflyPath_, mainFile_, target_, $task)
|
|
143
|
-
"""
|
|
144
|
-
|
|
145
|
-
internalMainPackagePair(buildSystem: BuildSystem): Pair[String, String]
|
|
146
|
-
target node async """
|
|
147
|
-
return {first_: buildSystem_.mainPackagePair_.group_, second_: buildSystem_.mainPackagePair_.name_}
|
|
148
|
-
"""
|
|
1
|
+
capability BuildSystem {}
|
|
2
|
+
capability BrowserCode(packageGroup: String, packageName: String, mainFile: Path, assetSystem: AssetSystem)
|
|
3
|
+
capability BrowserBundle(assetSystem: AssetSystem)
|
|
4
|
+
|
|
5
|
+
extend self: BuildSystem {
|
|
6
|
+
|
|
7
|
+
compileForBrowser(mainFile: String): BrowserCode {
|
|
8
|
+
// TODO: Check that the mainFile is in the current package directory
|
|
9
|
+
internalCompile(self, internalPath(self, mainFile), "browser")
|
|
10
|
+
let streams = internalListDirectory(internalPath(self, ".firefly/output/browser"))
|
|
11
|
+
let mainPackagePair = internalMainPackagePair(self)
|
|
12
|
+
BrowserCode(
|
|
13
|
+
packageGroup = mainPackagePair.first
|
|
14
|
+
packageName = mainPackagePair.second
|
|
15
|
+
mainFile = internalPath(self, mainFile)
|
|
16
|
+
assetSystem = AssetSystem(streams.toMap())
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
buildMode(): Bool
|
|
21
|
+
target node async "return !!self_.buildMode_"
|
|
22
|
+
|
|
23
|
+
setAssets(assetSystem: AssetSystem): Unit
|
|
24
|
+
target node async "self_.assets_ = assetSystem_"
|
|
25
|
+
|
|
26
|
+
packageAssets(): AssetSystem {
|
|
27
|
+
let streams = internalListDirectory(internalPath(self, "."))
|
|
28
|
+
AssetSystem(streams.toMap())
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
dependencyAssets(user: String, package: String): AssetSystem {
|
|
32
|
+
panic("dependencyAssets not yet implemented")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
arguments(): List[String]
|
|
36
|
+
target node async "return self_.array_"
|
|
37
|
+
|
|
38
|
+
mainTask(): Task
|
|
39
|
+
target js async "return self_.task_"
|
|
40
|
+
|
|
41
|
+
crypto(): Crypto
|
|
42
|
+
target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
extend self: BrowserCode {
|
|
47
|
+
|
|
48
|
+
assets(): AssetSystem {
|
|
49
|
+
self.assetSystem
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
bundle(minify: Bool = True, sourceMap: Bool = False): BrowserBundle {
|
|
53
|
+
let prefix = ".firefly/output/browser"
|
|
54
|
+
let mainJsBaseFile = self.mainFile.base().removeLast(".ff").grab() + ".mjs"
|
|
55
|
+
let mainJsFile = prefix + "/" + self.packageGroup + "/" + self.packageName + "/" + mainJsBaseFile
|
|
56
|
+
let mainDirectory = self.mainFile.parent().grab()
|
|
57
|
+
let file = prefix + "/Main.bundle.js"
|
|
58
|
+
internalCallEsBuild(self, mainJsFile = mainJsFile, outputPath = file, minify = minify, sourceMap = sourceMap)
|
|
59
|
+
let assets = AssetSystem([
|
|
60
|
+
Pair(file.dropFirst(prefix.size()), {mainDirectory.path(file).readStream()})
|
|
61
|
+
...if(sourceMap) {[
|
|
62
|
+
Pair(file.dropFirst(prefix.size()) + ".map", {mainDirectory.path(file + ".map").readStream()})
|
|
63
|
+
]} else {[]}
|
|
64
|
+
].toMap())
|
|
65
|
+
BrowserBundle(assets)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
extend self: BrowserBundle {
|
|
71
|
+
|
|
72
|
+
assets(): AssetSystem {
|
|
73
|
+
self.assetSystem
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
internalCallEsBuild(
|
|
80
|
+
self: BrowserCode
|
|
81
|
+
mainJsFile: String
|
|
82
|
+
outputPath: String
|
|
83
|
+
minify: Bool
|
|
84
|
+
sourceMap: Bool
|
|
85
|
+
): Unit
|
|
86
|
+
target node async """
|
|
87
|
+
import * as esbuild from 'esbuild'
|
|
88
|
+
return await esbuild.build({
|
|
89
|
+
entryPoints: [mainJsFile_],
|
|
90
|
+
bundle: true,
|
|
91
|
+
minify: minify_,
|
|
92
|
+
sourcemap: sourceMap_,
|
|
93
|
+
platform: 'browser',
|
|
94
|
+
target: 'es6',
|
|
95
|
+
external: ['../../../node_modules/*'], // TODO
|
|
96
|
+
outfile: outputPath_
|
|
97
|
+
})
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
internalNodeCallEsBuild(
|
|
101
|
+
self: NodeSystem
|
|
102
|
+
mainJsFile: String
|
|
103
|
+
outputPath: String
|
|
104
|
+
minify: Bool
|
|
105
|
+
): Unit
|
|
106
|
+
target node async """
|
|
107
|
+
import * as esbuild from 'esbuild'
|
|
108
|
+
return await esbuild.build({
|
|
109
|
+
entryPoints: [mainJsFile_],
|
|
110
|
+
bundle: true,
|
|
111
|
+
minify: minify_,
|
|
112
|
+
sourcemap: true,
|
|
113
|
+
platform: 'node',
|
|
114
|
+
target: 'es6',
|
|
115
|
+
external: ['../../../node_modules/*'], // TODO
|
|
116
|
+
outfile: outputPath_
|
|
117
|
+
})
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
internalListDirectory(path: Path): List[Pair[String, () => Stream[Buffer]]] {
|
|
121
|
+
function go(currentPath: Path): Stream[Path] {
|
|
122
|
+
currentPath.entries().flatMap {file =>
|
|
123
|
+
if(file.isDirectory()) {
|
|
124
|
+
go(file.path())
|
|
125
|
+
} else {
|
|
126
|
+
[file.path()].toStream()
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
go(path).map {file =>
|
|
131
|
+
Pair("/" + file.relativeTo(path).replace("\\", "/"), {file.readStream()})
|
|
132
|
+
}.toList()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
internalPath(buildSystem: BuildSystem, absoluteOrRelative: String): Path
|
|
136
|
+
target node async """
|
|
137
|
+
return absoluteOrRelative_
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
internalCompile(buildSystem: BuildSystem, mainFile: Path, target: String): Unit
|
|
141
|
+
target node async """
|
|
142
|
+
return await $firefly_compiler.buildViaBuildSystem_$(buildSystem_, buildSystem_.fireflyPath_, mainFile_, target_, $task)
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
internalMainPackagePair(buildSystem: BuildSystem): Pair[String, String]
|
|
146
|
+
target node async """
|
|
147
|
+
return {first_: buildSystem_.mainPackagePair_.group_, second_: buildSystem_.mainPackagePair_.name_}
|
|
148
|
+
"""
|
package/core/Crypto.ff
CHANGED
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
capability Crypto {}
|
|
2
|
-
|
|
3
|
-
extend self: Crypto {
|
|
4
|
-
|
|
5
|
-
randomUuid(): String
|
|
6
|
-
target js async """
|
|
7
|
-
return self_.randomUUID();
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
randomBuffer(size: Int): Buffer {
|
|
11
|
-
let buffer = Buffer.new(size)
|
|
12
|
-
self.randomizeBuffer(buffer)
|
|
13
|
-
buffer
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
randomizeBuffer(buffer: Buffer): Unit
|
|
17
|
-
target js async """
|
|
18
|
-
self_.getRandomValues(new Uint8Array(buffer_.buffer, buffer_.byteOffset, buffer_.byteLength));
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
hmacSha256(key: Buffer, buffer: Buffer): Buffer
|
|
22
|
-
target js async """
|
|
23
|
-
const cryptoKey = await self_.subtle.importKey(
|
|
24
|
-
'raw',
|
|
25
|
-
key_,
|
|
26
|
-
{name: 'HMAC', hash: {name: 'SHA-256'}},
|
|
27
|
-
false,
|
|
28
|
-
['sign']
|
|
29
|
-
);
|
|
30
|
-
const signature = await self_.subtle.sign(
|
|
31
|
-
'HMAC',
|
|
32
|
-
cryptoKey,
|
|
33
|
-
buffer_
|
|
34
|
-
);
|
|
35
|
-
return new DataView(signature);
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
sha256(buffer: Buffer): Buffer
|
|
39
|
-
target js async """
|
|
40
|
-
let hash = await self_.subtle.digest('SHA-256', buffer_);
|
|
41
|
-
return new DataView(hash);
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
hashPassword(password: String, iterations: Int = 600000): String {
|
|
45
|
-
let salt = self.randomBuffer(16)
|
|
46
|
-
let hash = internalHashPassword(self, salt, password.toBuffer(), iterations)
|
|
47
|
-
"$pbkdf2-sha256-hex$" + iterations + "$" + salt.toHex() + "$" + hash.toHex()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
checkPassword(password: String, passwordHash: String): Bool {
|
|
51
|
-
passwordHash.split('$').{
|
|
52
|
-
| ["", "pbkdf2-sha256-hex", iterationsText, saltText, hashText] {
|
|
53
|
-
iterationsText.getInt() | Some(iterations)
|
|
54
|
-
} =>
|
|
55
|
-
let computedHash =
|
|
56
|
-
internalHashPassword(self, Buffer.fromHex(saltText), password.toBuffer(), iterations)
|
|
57
|
-
let hash = Buffer.fromHex(hashText)
|
|
58
|
-
self.constantTimeEquals(computedHash, hash)
|
|
59
|
-
| _ => False
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
constantTimeEquals(buffer1: Buffer, buffer2: Buffer): Bool {
|
|
64
|
-
if(buffer1.size() != buffer2.size()) {False} else:
|
|
65
|
-
mutable v = 0
|
|
66
|
-
mutable i = 0
|
|
67
|
-
while {i < buffer1.size()} {
|
|
68
|
-
v = v.bitOr(buffer1.grabUint8(i).bitXor(buffer2.grabUint8(i)))
|
|
69
|
-
i += 1
|
|
70
|
-
}
|
|
71
|
-
v == 0
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
internalHashPassword(system: Crypto, salt: Buffer, password: Buffer, iterations: Int): Buffer
|
|
77
|
-
target js async """
|
|
78
|
-
const keyMaterial = await crypto.subtle.importKey(
|
|
79
|
-
'raw',
|
|
80
|
-
password_,
|
|
81
|
-
{name: 'PBKDF2'},
|
|
82
|
-
false,
|
|
83
|
-
['deriveBits']
|
|
84
|
-
);
|
|
85
|
-
const hashBuffer = await crypto.subtle.deriveBits(
|
|
86
|
-
{
|
|
87
|
-
name: 'PBKDF2',
|
|
88
|
-
salt: salt_,
|
|
89
|
-
iterations: iterations_,
|
|
90
|
-
hash: 'SHA-256'
|
|
91
|
-
},
|
|
92
|
-
keyMaterial,
|
|
93
|
-
256
|
|
94
|
-
);
|
|
95
|
-
return new DataView(hashBuffer);
|
|
96
|
-
"""
|
|
1
|
+
capability Crypto {}
|
|
2
|
+
|
|
3
|
+
extend self: Crypto {
|
|
4
|
+
|
|
5
|
+
randomUuid(): String
|
|
6
|
+
target js async """
|
|
7
|
+
return self_.randomUUID();
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
randomBuffer(size: Int): Buffer {
|
|
11
|
+
let buffer = Buffer.new(size)
|
|
12
|
+
self.randomizeBuffer(buffer)
|
|
13
|
+
buffer
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
randomizeBuffer(buffer: Buffer): Unit
|
|
17
|
+
target js async """
|
|
18
|
+
self_.getRandomValues(new Uint8Array(buffer_.buffer, buffer_.byteOffset, buffer_.byteLength));
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
hmacSha256(key: Buffer, buffer: Buffer): Buffer
|
|
22
|
+
target js async """
|
|
23
|
+
const cryptoKey = await self_.subtle.importKey(
|
|
24
|
+
'raw',
|
|
25
|
+
key_,
|
|
26
|
+
{name: 'HMAC', hash: {name: 'SHA-256'}},
|
|
27
|
+
false,
|
|
28
|
+
['sign']
|
|
29
|
+
);
|
|
30
|
+
const signature = await self_.subtle.sign(
|
|
31
|
+
'HMAC',
|
|
32
|
+
cryptoKey,
|
|
33
|
+
buffer_
|
|
34
|
+
);
|
|
35
|
+
return new DataView(signature);
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
sha256(buffer: Buffer): Buffer
|
|
39
|
+
target js async """
|
|
40
|
+
let hash = await self_.subtle.digest('SHA-256', buffer_);
|
|
41
|
+
return new DataView(hash);
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
hashPassword(password: String, iterations: Int = 600000): String {
|
|
45
|
+
let salt = self.randomBuffer(16)
|
|
46
|
+
let hash = internalHashPassword(self, salt, password.toBuffer(), iterations)
|
|
47
|
+
"$pbkdf2-sha256-hex$" + iterations + "$" + salt.toHex() + "$" + hash.toHex()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
checkPassword(password: String, passwordHash: String): Bool {
|
|
51
|
+
passwordHash.split('$').{
|
|
52
|
+
| ["", "pbkdf2-sha256-hex", iterationsText, saltText, hashText] {
|
|
53
|
+
iterationsText.getInt() | Some(iterations)
|
|
54
|
+
} =>
|
|
55
|
+
let computedHash =
|
|
56
|
+
internalHashPassword(self, Buffer.fromHex(saltText), password.toBuffer(), iterations)
|
|
57
|
+
let hash = Buffer.fromHex(hashText)
|
|
58
|
+
self.constantTimeEquals(computedHash, hash)
|
|
59
|
+
| _ => False
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
constantTimeEquals(buffer1: Buffer, buffer2: Buffer): Bool {
|
|
64
|
+
if(buffer1.size() != buffer2.size()) {False} else:
|
|
65
|
+
mutable v = 0
|
|
66
|
+
mutable i = 0
|
|
67
|
+
while {i < buffer1.size()} {
|
|
68
|
+
v = v.bitOr(buffer1.grabUint8(i).bitXor(buffer2.grabUint8(i)))
|
|
69
|
+
i += 1
|
|
70
|
+
}
|
|
71
|
+
v == 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
internalHashPassword(system: Crypto, salt: Buffer, password: Buffer, iterations: Int): Buffer
|
|
77
|
+
target js async """
|
|
78
|
+
const keyMaterial = await crypto.subtle.importKey(
|
|
79
|
+
'raw',
|
|
80
|
+
password_,
|
|
81
|
+
{name: 'PBKDF2'},
|
|
82
|
+
false,
|
|
83
|
+
['deriveBits']
|
|
84
|
+
);
|
|
85
|
+
const hashBuffer = await crypto.subtle.deriveBits(
|
|
86
|
+
{
|
|
87
|
+
name: 'PBKDF2',
|
|
88
|
+
salt: salt_,
|
|
89
|
+
iterations: iterations_,
|
|
90
|
+
hash: 'SHA-256'
|
|
91
|
+
},
|
|
92
|
+
keyMaterial,
|
|
93
|
+
256
|
|
94
|
+
);
|
|
95
|
+
return new DataView(hashBuffer);
|
|
96
|
+
"""
|
package/core/Equal.ff
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
trait T: Equal {
|
|
2
|
-
equals(x: T, y: T): Bool
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
notEquals[T: Equal](x: T, y: T): Bool {
|
|
6
|
-
!equals(x, y)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
instance Nothing: Equal {
|
|
10
|
-
equals(x: Nothing, y: Nothing): Bool {True}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
instance Bool: Equal {
|
|
14
|
-
equals(x: Bool, y: Bool): Bool
|
|
15
|
-
target js sync """return x_ === y_"""
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
instance Char: Equal {
|
|
19
|
-
equals(x: Char, y: Char): Bool
|
|
20
|
-
target js sync """return x_ === y_"""
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
instance Int: Equal {
|
|
24
|
-
equals(x: Int, y: Int): Bool
|
|
25
|
-
target js sync """return x_ === y_"""
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
instance Float: Equal {
|
|
29
|
-
equals(x: Float, y: Float): Bool
|
|
30
|
-
target js sync """return x_ === y_"""
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
instance String: Equal {
|
|
34
|
-
equals(x: String, y: String): Bool
|
|
35
|
-
target js sync """return x_ === y_"""
|
|
36
|
-
}
|
|
1
|
+
trait T: Equal {
|
|
2
|
+
equals(x: T, y: T): Bool
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
notEquals[T: Equal](x: T, y: T): Bool {
|
|
6
|
+
!equals(x, y)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
instance Nothing: Equal {
|
|
10
|
+
equals(x: Nothing, y: Nothing): Bool {True}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
instance Bool: Equal {
|
|
14
|
+
equals(x: Bool, y: Bool): Bool
|
|
15
|
+
target js sync """return x_ === y_"""
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
instance Char: Equal {
|
|
19
|
+
equals(x: Char, y: Char): Bool
|
|
20
|
+
target js sync """return x_ === y_"""
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
instance Int: Equal {
|
|
24
|
+
equals(x: Int, y: Int): Bool
|
|
25
|
+
target js sync """return x_ === y_"""
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
instance Float: Equal {
|
|
29
|
+
equals(x: Float, y: Float): Bool
|
|
30
|
+
target js sync """return x_ === y_"""
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
instance String: Equal {
|
|
34
|
+
equals(x: String, y: String): Bool
|
|
35
|
+
target js sync """return x_ === y_"""
|
|
36
|
+
}
|