firefly-compiler 0.4.19 → 0.4.21
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/compiler/Builder.ff +23 -13
- package/compiler/JsEmitter.ff +120 -76
- package/compiler/LspHook.ff +17 -3
- package/compiler/Main.ff +13 -7
- package/compiler/Parser.ff +11 -13
- package/compiler/Resolver.ff +15 -15
- package/compiler/Syntax.ff +1 -0
- package/core/Array.ff +6 -4
- package/core/Int.ff +12 -12
- package/core/Json.ff +2 -2
- package/core/List.ff +6 -4
- package/experimental/benchmarks/ListGrab.ff +23 -0
- package/experimental/benchmarks/ListGrab.java +55 -0
- package/experimental/benchmarks/Pyrotek45.ff +30 -0
- package/experimental/benchmarks/Pyrotek45.java +64 -0
- package/experimental/tests/TestJson.ff +26 -0
- package/lsp/CompletionHandler.ff +14 -14
- package/lsp/Handler.ff +56 -60
- package/lsp/SignatureHelpHandler.ff +5 -4
- package/lsp/SymbolHandler.ff +18 -4
- package/lsp/TestReferences.ff +15 -0
- package/lsp/TestReferencesCase.ff +8 -0
- package/output/js/ff/compiler/Builder.mjs +50 -44
- package/output/js/ff/compiler/Dependencies.mjs +0 -2
- package/output/js/ff/compiler/Deriver.mjs +16 -140
- package/output/js/ff/compiler/Dictionaries.mjs +8 -222
- package/output/js/ff/compiler/Environment.mjs +12 -154
- package/output/js/ff/compiler/Inference.mjs +127 -1013
- package/output/js/ff/compiler/JsEmitter.mjs +434 -2344
- package/output/js/ff/compiler/JsImporter.mjs +0 -12
- package/output/js/ff/compiler/LspHook.mjs +548 -151
- package/output/js/ff/compiler/Main.mjs +96 -550
- package/output/js/ff/compiler/Parser.mjs +58 -390
- package/output/js/ff/compiler/Patterns.mjs +20 -200
- package/output/js/ff/compiler/Resolver.mjs +26 -340
- package/output/js/ff/compiler/Substitution.mjs +2 -160
- package/output/js/ff/compiler/Syntax.mjs +449 -3293
- package/output/js/ff/compiler/Token.mjs +9 -1095
- package/output/js/ff/compiler/Tokenizer.mjs +4 -2
- package/output/js/ff/compiler/Unification.mjs +26 -360
- package/output/js/ff/compiler/Wildcards.mjs +0 -86
- package/output/js/ff/compiler/Workspace.mjs +8 -96
- package/output/js/ff/core/Array.mjs +15 -8
- package/output/js/ff/core/AssetSystem.mjs +4 -14
- package/output/js/ff/core/Bool.mjs +0 -12
- package/output/js/ff/core/Core.mjs +0 -30
- package/output/js/ff/core/Int.mjs +24 -24
- package/output/js/ff/core/IntMap.mjs +0 -8
- package/output/js/ff/core/Json.mjs +2 -42
- package/output/js/ff/core/List.mjs +23 -32
- package/output/js/ff/core/Lock.mjs +0 -10
- package/output/js/ff/core/Map.mjs +0 -24
- package/output/js/ff/core/Option.mjs +10 -286
- package/output/js/ff/core/Ordering.mjs +16 -158
- package/output/js/ff/core/Pair.mjs +2 -34
- package/output/js/ff/core/Path.mjs +2 -28
- package/output/js/ff/core/Random.mjs +4 -4
- package/output/js/ff/core/RbMap.mjs +56 -644
- package/output/js/ff/core/Show.mjs +0 -16
- package/output/js/ff/core/Stream.mjs +14 -144
- package/output/js/ff/core/StringMap.mjs +0 -8
- package/output/js/ff/core/Try.mjs +4 -108
- package/output/js/ff/core/Unit.mjs +2 -16
- package/package.json +1 -1
- package/postgresql/Pg.ff +23 -23
- package/vscode/client/src/extension.ts +30 -2
- package/vscode/package.json +17 -1
- package/core/Stack.ff +0 -250
package/compiler/Resolver.ff
CHANGED
|
@@ -49,16 +49,16 @@ extend self: Resolver {
|
|
|
49
49
|
|
|
50
50
|
resolveModule(module: Module, otherModules: List[Module]): Module {
|
|
51
51
|
let moduleNamespace =
|
|
52
|
-
module.file.replace("\\", "/").reverse().takeWhile {
|
|
52
|
+
module.file.replace("\\", "/").reverse().takeWhile {_ != '/'}.reverse().takeWhile {_ != '.'}
|
|
53
53
|
let self2 = self.processImports(module.imports, otherModules)
|
|
54
54
|
let self3 = self2.processDefinitions(module, None)
|
|
55
55
|
let module2 = module.Module(
|
|
56
|
-
types = module.types.map {
|
|
57
|
-
traits = module.traits.map {
|
|
58
|
-
instances = module.instances.map {
|
|
59
|
-
extends = module.extends.map {
|
|
60
|
-
lets = module.lets.map {
|
|
61
|
-
functions = module.functions.map {
|
|
56
|
+
types = module.types.map {self3.resolveTypeDefinition(_)}
|
|
57
|
+
traits = module.traits.map {self3.resolveTraitDefinition(_)}
|
|
58
|
+
instances = module.instances.map {self3.resolveInstanceDefinition(_)}
|
|
59
|
+
extends = module.extends.map {self3.resolveExtendDefinition(_)}
|
|
60
|
+
lets = module.lets.map {self3.resolveLetDefinition(_, True)}
|
|
61
|
+
functions = module.functions.map {self3.resolveFunctionDefinition(_, True, False)}
|
|
62
62
|
)
|
|
63
63
|
module2.instances.each {_.typeArguments.each {self3.checkInstanceType(_)}}
|
|
64
64
|
module2
|
|
@@ -135,7 +135,7 @@ extend self: Resolver {
|
|
|
135
135
|
resolveTypeDefinition(definition: DType): DType {
|
|
136
136
|
if(self.lspHook.isAt(definition.at)) {
|
|
137
137
|
self.lspHook.emit(
|
|
138
|
-
ResolveSymbolHook(SymbolHook(definition.name, definition.at, definition.at), None)
|
|
138
|
+
ResolveSymbolHook(SymbolHook(definition.name, definition.at, definition.at), None, topLevel = True)
|
|
139
139
|
)
|
|
140
140
|
}
|
|
141
141
|
let generics = definition.generics.map {g => Pair(g, g)}.toMap()
|
|
@@ -168,7 +168,7 @@ extend self: Resolver {
|
|
|
168
168
|
variants = definition.variants.map {v =>
|
|
169
169
|
if(self.lspHook.isAt(v.at)) {
|
|
170
170
|
self.lspHook.emit(
|
|
171
|
-
ResolveSymbolHook(SymbolHook(v.name, v.at, v.at), None)
|
|
171
|
+
ResolveSymbolHook(SymbolHook(v.name, v.at, v.at), None, topLevel = True)
|
|
172
172
|
)
|
|
173
173
|
}
|
|
174
174
|
v.Variant(fields = v.fields.map {f =>
|
|
@@ -191,7 +191,7 @@ extend self: Resolver {
|
|
|
191
191
|
if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(definition.at)) {
|
|
192
192
|
self.lspHook.emit(
|
|
193
193
|
ResolveSymbolHook(
|
|
194
|
-
SymbolHook(definition.name, definition.at, definition.at), None
|
|
194
|
+
SymbolHook(definition.name, definition.at, definition.at), None, topLevel = True
|
|
195
195
|
)
|
|
196
196
|
)
|
|
197
197
|
}
|
|
@@ -221,7 +221,7 @@ extend self: Resolver {
|
|
|
221
221
|
if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(traitDefinedAt)) {
|
|
222
222
|
self.lspHook.emit(
|
|
223
223
|
ResolveSymbolHook(
|
|
224
|
-
SymbolHook(definition.traitName, definition.at, traitDefinedAt), None
|
|
224
|
+
SymbolHook(definition.traitName, definition.at, traitDefinedAt), None, topLevel = True
|
|
225
225
|
)
|
|
226
226
|
)
|
|
227
227
|
}
|
|
@@ -266,7 +266,7 @@ extend self: Resolver {
|
|
|
266
266
|
if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(definition.at)) {
|
|
267
267
|
self.lspHook.emit(
|
|
268
268
|
ResolveSymbolHook(
|
|
269
|
-
SymbolHook(definition.name, definition.at, definition.at), None
|
|
269
|
+
SymbolHook(definition.name, definition.at, definition.at), None, topLevel = topLevel
|
|
270
270
|
)
|
|
271
271
|
)
|
|
272
272
|
}
|
|
@@ -287,7 +287,7 @@ extend self: Resolver {
|
|
|
287
287
|
if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(at)) {
|
|
288
288
|
self.lspHook.emit(
|
|
289
289
|
ResolveSymbolHook(
|
|
290
|
-
SymbolHook(e.name, e.at, at), None
|
|
290
|
+
SymbolHook(e.name, e.at, at), None, topLevel = True
|
|
291
291
|
)
|
|
292
292
|
)
|
|
293
293
|
}
|
|
@@ -369,7 +369,7 @@ extend self: Resolver {
|
|
|
369
369
|
if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(e.at)) {
|
|
370
370
|
self.lspHook.emit(
|
|
371
371
|
ResolveSymbolHook(
|
|
372
|
-
SymbolHook(e.name, e.at, e.at), None
|
|
372
|
+
SymbolHook(e.name, e.at, e.at), None, topLevel = False
|
|
373
373
|
)
|
|
374
374
|
)
|
|
375
375
|
}
|
|
@@ -492,7 +492,7 @@ extend self: Resolver {
|
|
|
492
492
|
resolveSignature(signature: Signature, topLevel: Bool, isInstanceMethod: Bool): Signature {
|
|
493
493
|
if(self.lspHook.isAt(signature.at) || self.lspHook.isDefinedAt(signature.at)) {
|
|
494
494
|
self.lspHook.emit(
|
|
495
|
-
ResolveSignatureHook(signature, isInstanceMethod)
|
|
495
|
+
ResolveSignatureHook(signature, isInstanceMethod, topLevel = topLevel)
|
|
496
496
|
)
|
|
497
497
|
}
|
|
498
498
|
let newSignature = if(topLevel) {
|
package/compiler/Syntax.ff
CHANGED
package/core/Array.ff
CHANGED
|
@@ -35,10 +35,7 @@ extend self[T]: Array[T] {
|
|
|
35
35
|
|
|
36
36
|
grab(index: Int): T
|
|
37
37
|
target js sync """
|
|
38
|
-
|
|
39
|
-
ff_core_Try.internalThrowGrabException_()
|
|
40
|
-
}
|
|
41
|
-
return self_.array[index_]
|
|
38
|
+
return self_.array[index_] ?? internalGrab_(self_, index_);
|
|
42
39
|
"""
|
|
43
40
|
|
|
44
41
|
grabFirst(): T {self.grab(0)}
|
|
@@ -261,3 +258,8 @@ sortRange[T](array: Array[T], compare: (T, T) => Ordering, start: Int, end: Int)
|
|
|
261
258
|
}
|
|
262
259
|
}
|
|
263
260
|
}
|
|
261
|
+
|
|
262
|
+
internalGrab[T](self: Array[T], index: Int): T
|
|
263
|
+
target js sync """
|
|
264
|
+
return index_ < 0 || index_ >= self_.array.length ? ff_core_Try.internalThrowGrabException_() : self_.array[index_];
|
|
265
|
+
"""
|
package/core/Int.ff
CHANGED
|
@@ -27,23 +27,23 @@ extend self: Int {
|
|
|
27
27
|
target js sync "return signed_ ? self_ >> bits_ : self_ >>> bits_;"
|
|
28
28
|
|
|
29
29
|
to(inclusiveEnd: Int): List[Int] {
|
|
30
|
-
|
|
31
|
-
mutable n =
|
|
32
|
-
while {
|
|
33
|
-
result
|
|
34
|
-
n
|
|
30
|
+
let result = Array.make()
|
|
31
|
+
mutable n = self
|
|
32
|
+
while {n <= inclusiveEnd} {
|
|
33
|
+
result.push(n)
|
|
34
|
+
n += 1
|
|
35
35
|
}
|
|
36
|
-
result
|
|
36
|
+
result.drain()
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
until(exclusiveEnd: Int): List[Int] {
|
|
40
|
-
|
|
41
|
-
mutable n =
|
|
42
|
-
while {
|
|
43
|
-
result
|
|
44
|
-
n
|
|
40
|
+
let result = Array.make()
|
|
41
|
+
mutable n = self
|
|
42
|
+
while {n < exclusiveEnd} {
|
|
43
|
+
result.push(n)
|
|
44
|
+
n += 1
|
|
45
45
|
}
|
|
46
|
-
result
|
|
46
|
+
result.drain()
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
min(that: Int): Int {
|
package/core/Json.ff
CHANGED
|
@@ -405,8 +405,8 @@ internalCompare(a: Json, b: Json): Int
|
|
|
405
405
|
} else if (typeof a_ === 'number' || typeof b_ === 'number') {
|
|
406
406
|
if(typeof b_ !== 'number') return -1;
|
|
407
407
|
if(typeof a_ !== 'number') return 1;
|
|
408
|
-
if(
|
|
409
|
-
if(
|
|
408
|
+
if(isNaN(a_)) return isNaN(b_) ? 0 : -1;
|
|
409
|
+
if(isNaN(b_)) return 1;
|
|
410
410
|
return a_ < b_ ? -1 : 1;
|
|
411
411
|
} else if (typeof a_ === 'string' || typeof b_ === 'string') {
|
|
412
412
|
if(typeof b_ !== 'string') return -1;
|
package/core/List.ff
CHANGED
|
@@ -47,10 +47,7 @@ extend self[T]: List[T] {
|
|
|
47
47
|
|
|
48
48
|
grab(index: Int): T
|
|
49
49
|
target js sync """
|
|
50
|
-
|
|
51
|
-
ff_core_Try.internalThrowGrabException_()
|
|
52
|
-
}
|
|
53
|
-
return self_[index_]
|
|
50
|
+
return self_[index_] ?? internalGrab_(self_, index_);
|
|
54
51
|
"""
|
|
55
52
|
|
|
56
53
|
first(): Option[T] {self.get(0)}
|
|
@@ -411,3 +408,8 @@ instance List[T: Order]: Order {
|
|
|
411
408
|
|
|
412
409
|
internalSame[T](left: List[T], right: List[T]): Bool
|
|
413
410
|
target js sync "return left_ === right_"
|
|
411
|
+
|
|
412
|
+
internalGrab[T](self: List[T], index: Int): T
|
|
413
|
+
target js sync """
|
|
414
|
+
return index_ < 0 || index_ >= self_.length ? ff_core_Try.internalThrowGrabException_() : self_[index_];
|
|
415
|
+
"""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
nodeMain(system: NodeSystem) {
|
|
2
|
+
let list = 1.to(10000)
|
|
3
|
+
benchmark(list, 100000)
|
|
4
|
+
let time = system.mainTask().time {
|
|
5
|
+
benchmark(list, 100000)
|
|
6
|
+
}
|
|
7
|
+
Log.trace(time.second.show())
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
benchmark(list: List[Int], iterations: Int): Int {
|
|
11
|
+
mutable sum = 0
|
|
12
|
+
mutable i = 0
|
|
13
|
+
while {i < iterations} {
|
|
14
|
+
mutable j = 0
|
|
15
|
+
sum = 0
|
|
16
|
+
while {j < 10000} {
|
|
17
|
+
sum += list.grab(j)
|
|
18
|
+
j += 1
|
|
19
|
+
}
|
|
20
|
+
i += 1
|
|
21
|
+
}
|
|
22
|
+
sum
|
|
23
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
nodeMain(system: NodeSystem) {
|
|
4
|
+
let list = 1.to(10000)
|
|
5
|
+
benchmark(list, 10000)
|
|
6
|
+
let time = system.mainTask().time {
|
|
7
|
+
benchmark(list, 10000)
|
|
8
|
+
}
|
|
9
|
+
Log.trace(time.second.show())
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
benchmark(list: List[Int], iterations: Int): Int {
|
|
13
|
+
mutable sum = 0
|
|
14
|
+
mutable i = 0
|
|
15
|
+
while {i < iterations} {
|
|
16
|
+
mutable j = 0
|
|
17
|
+
while {j < 10000} {
|
|
18
|
+
sum += list.grab(j)
|
|
19
|
+
j += 1
|
|
20
|
+
}
|
|
21
|
+
i += 1
|
|
22
|
+
}
|
|
23
|
+
sum
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// Rewrite the above to Java
|
|
29
|
+
|
|
30
|
+
import java.util.ArrayList;
|
|
31
|
+
|
|
32
|
+
public class ListGrab {
|
|
33
|
+
public static void main(String[] args) {
|
|
34
|
+
ArrayList<Integer> list = new ArrayList<>();
|
|
35
|
+
for (int i = 1; i <= 10000; i++) {
|
|
36
|
+
list.add(i);
|
|
37
|
+
}
|
|
38
|
+
benchmark(list, 100000);
|
|
39
|
+
long time = System.currentTimeMillis();
|
|
40
|
+
benchmark(list, 100000);
|
|
41
|
+
time = System.currentTimeMillis() - time;
|
|
42
|
+
System.out.println(time / 1000.0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static long benchmark(ArrayList<Integer> list, int iterations) {
|
|
46
|
+
long sum = 0;
|
|
47
|
+
for (int i = 0; i < iterations; i++) {
|
|
48
|
+
sum = 0;
|
|
49
|
+
for (int j = 0; j < 10000; j++) {
|
|
50
|
+
sum += list.get(j);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return sum;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
nodeMain(system: NodeSystem) {
|
|
2
|
+
benchmark()
|
|
3
|
+
let time = system.mainTask().time {
|
|
4
|
+
benchmark()
|
|
5
|
+
}
|
|
6
|
+
Log.trace(time.second.show())
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
benchmark() {
|
|
10
|
+
mutable num = 20000
|
|
11
|
+
let v = num
|
|
12
|
+
mutable i = 1
|
|
13
|
+
mutable j = 1
|
|
14
|
+
mutable sum = 0
|
|
15
|
+
while {i < v} {
|
|
16
|
+
j = 1
|
|
17
|
+
while {j < num - 1} {
|
|
18
|
+
if(num % j == 0) {
|
|
19
|
+
sum += j
|
|
20
|
+
}
|
|
21
|
+
j += 1
|
|
22
|
+
}
|
|
23
|
+
if(num == sum) {
|
|
24
|
+
Log.show(sum)
|
|
25
|
+
}
|
|
26
|
+
sum = 0
|
|
27
|
+
num -= 1
|
|
28
|
+
i += 1
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
nodeMain(system: NodeSystem) {
|
|
3
|
+
benchmark()
|
|
4
|
+
let time = system.mainTask().time {
|
|
5
|
+
benchmark()
|
|
6
|
+
}
|
|
7
|
+
Log.trace(time.second.show())
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
benchmark() {
|
|
11
|
+
mutable num = 20000
|
|
12
|
+
let v = num
|
|
13
|
+
mutable i = 1
|
|
14
|
+
mutable j = 1
|
|
15
|
+
mutable sum = 0
|
|
16
|
+
while {i < v} {
|
|
17
|
+
j = 1
|
|
18
|
+
while {j < num - 1} {
|
|
19
|
+
if(num % j == 0) {
|
|
20
|
+
sum += j
|
|
21
|
+
}
|
|
22
|
+
j += 1
|
|
23
|
+
}
|
|
24
|
+
if(num == sum) {
|
|
25
|
+
Log.show(sum)
|
|
26
|
+
}
|
|
27
|
+
sum = 0
|
|
28
|
+
num -= 1
|
|
29
|
+
i += 1
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
// Rewrite this in Java
|
|
35
|
+
|
|
36
|
+
public class Pyrotek45 {
|
|
37
|
+
public static void main(String[] args) {
|
|
38
|
+
benchmark();
|
|
39
|
+
long time = System.currentTimeMillis();
|
|
40
|
+
benchmark();
|
|
41
|
+
time = System.currentTimeMillis() - time;
|
|
42
|
+
System.out.println(time / 1000.0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static void benchmark() {
|
|
46
|
+
int num = 20000;
|
|
47
|
+
int v = num;
|
|
48
|
+
int i = 1;
|
|
49
|
+
int j = 1;
|
|
50
|
+
int sum = 0;
|
|
51
|
+
for (i = 1; i < v; i++) {
|
|
52
|
+
for (j = 1; j < num - 1; j++) {
|
|
53
|
+
if (num % j == 0) {
|
|
54
|
+
sum += j;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (num == sum) {
|
|
58
|
+
System.out.println(sum);
|
|
59
|
+
}
|
|
60
|
+
sum = 0;
|
|
61
|
+
num -= 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
nodeMain(system: NodeSystem) {
|
|
2
|
+
let jsons = [
|
|
3
|
+
Json.object()
|
|
4
|
+
Json.object().with("x", 1)
|
|
5
|
+
Json.object().with("y", 1)
|
|
6
|
+
Json.object().with("x", 1).with("y", 1)
|
|
7
|
+
Json.object().with("y", 2).with("x", 1)
|
|
8
|
+
Json.object().with("x", 1).with("y", 2)
|
|
9
|
+
Json.array([Json.int(3)])
|
|
10
|
+
Json.int(3)
|
|
11
|
+
Json.null()
|
|
12
|
+
Json.float(3.5)
|
|
13
|
+
Json.bool(True)
|
|
14
|
+
Json.bool(False)
|
|
15
|
+
]
|
|
16
|
+
system.writeLine(Show.show(Json.array(jsons.sort())))
|
|
17
|
+
jsons.each {json =>
|
|
18
|
+
let equal = jsons.filter {_ == json}
|
|
19
|
+
if(equal.size() != 1) {
|
|
20
|
+
system.writeLine(
|
|
21
|
+
"None-singleton equals: " +
|
|
22
|
+
equal.map {j => Show.show(json) + " == " + Show.show(j)}.join(" && ")
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
package/lsp/CompletionHandler.ff
CHANGED
|
@@ -748,8 +748,8 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
|
|
|
748
748
|
label = "webapp",
|
|
749
749
|
extra = " with frontend and backend",
|
|
750
750
|
snippet = [
|
|
751
|
-
"dependency ff:
|
|
752
|
-
"import
|
|
751
|
+
"dependency ff:webserver:0.0.0"
|
|
752
|
+
"import WebServer from ff:webserver"
|
|
753
753
|
""
|
|
754
754
|
"browserMain(system: BrowserSystem): Unit {"
|
|
755
755
|
" let response = system.httpClient().fetch(\"http://localhost:8080/hello\")"
|
|
@@ -758,19 +758,19 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
|
|
|
758
758
|
"}"
|
|
759
759
|
""
|
|
760
760
|
"nodeMain(system: NodeSystem): Unit {"
|
|
761
|
-
"
|
|
762
|
-
" if(request.
|
|
763
|
-
"
|
|
764
|
-
"
|
|
765
|
-
"
|
|
766
|
-
" } elseIf {request.
|
|
767
|
-
"
|
|
768
|
-
"
|
|
769
|
-
" } elseIf {request.
|
|
770
|
-
"
|
|
771
|
-
"
|
|
761
|
+
" WebServer.make(system, \"localhost\", 8080).listen {request =>"
|
|
762
|
+
" if(request.readPath() == \"/\") {"
|
|
763
|
+
" request.writeHeader(\"Content-Type\", \"text/html; charset=UTF-8\")"
|
|
764
|
+
" request.writeText(\"<!doctype html>\")"
|
|
765
|
+
" request.writeText(\"<script type='module' src='/js/script/script/WebApp.mjs'></script>\")"
|
|
766
|
+
" } elseIf {request.readPath() == \"/hello\"} {"
|
|
767
|
+
" request.writeHeader(\"Content-Type\", \"text/plain; charset=UTF-8\")"
|
|
768
|
+
" request.writeText(\"Hello from server!\")"
|
|
769
|
+
" } elseIf {request.readPath().startsWith(\"/js/\") && !request.readPath().contains(\"..\")} {"
|
|
770
|
+
" request.writeHeader(\"Content-Type\", \"text/javascript; charset=UTF-8\")"
|
|
771
|
+
" request.writeText(system.assets().readText(request.readPath()))"
|
|
772
772
|
" } else {"
|
|
773
|
-
"
|
|
773
|
+
" request.writeStatus(\"404 Not found\")"
|
|
774
774
|
" }"
|
|
775
775
|
" }"
|
|
776
776
|
"}"
|
package/lsp/Handler.ff
CHANGED
|
@@ -49,6 +49,8 @@ data TokenLocation(
|
|
|
49
49
|
followedByLeftBracket: Bool
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
+
data Definition(at: Location, name: String, local: Bool)
|
|
53
|
+
|
|
52
54
|
|
|
53
55
|
extend self: Handler {
|
|
54
56
|
|
|
@@ -194,18 +196,14 @@ extend self: Handler {
|
|
|
194
196
|
let uri = parameters.grab("textDocument").field("uri").grabString()
|
|
195
197
|
let path = system.pathFromUrl(uri)
|
|
196
198
|
let fireflyPath = system.path(".")
|
|
197
|
-
let
|
|
198
|
-
|
|
199
|
-
[]
|
|
200
|
-
} catch {| CompileError(at, message), error =>
|
|
199
|
+
let errors = Builder.check(system, fireflyPath, path, None, self.virtualFiles, LspHook.disabled(), True)
|
|
200
|
+
let diagnostics = errors.map {| CompileError(at, message) =>
|
|
201
201
|
let tokenLocation = self.findToken(system, at)
|
|
202
|
-
|
|
202
|
+
Json.object()
|
|
203
203
|
.with("range", self.tokenLocationToLspRange(tokenLocation))
|
|
204
204
|
.with("severity", 1)
|
|
205
205
|
.with("message", message)
|
|
206
|
-
|
|
207
|
-
} grab()
|
|
208
|
-
|
|
206
|
+
}
|
|
209
207
|
let o = Json.object()
|
|
210
208
|
.with("kind", "full")
|
|
211
209
|
.with("items", diagnostics)
|
|
@@ -217,18 +215,14 @@ extend self: Handler {
|
|
|
217
215
|
let uri = parameters.grab("textDocument").field("uri").grabString()
|
|
218
216
|
let path = system.pathFromUrl(uri)
|
|
219
217
|
let fireflyPath = system.path(".")
|
|
220
|
-
let
|
|
221
|
-
|
|
222
|
-
[]
|
|
223
|
-
} catch {| CompileError(at, message), error =>
|
|
218
|
+
let errors = Builder.check(system, fireflyPath, path, None, self.virtualFiles, LspHook.disabled(), True)
|
|
219
|
+
let diagnostics = errors.map {| CompileError(at, message) =>
|
|
224
220
|
let tokenLocation = self.findToken(system, at)
|
|
225
|
-
|
|
221
|
+
Json.object()
|
|
226
222
|
.with("range", self.tokenLocationToLspRange(tokenLocation))
|
|
227
223
|
.with("severity", 1)
|
|
228
224
|
.with("message", message)
|
|
229
|
-
|
|
230
|
-
} grab()
|
|
231
|
-
|
|
225
|
+
}
|
|
232
226
|
Json.object()
|
|
233
227
|
.with("uri", uri)
|
|
234
228
|
.with("version", parameters.grab("textDocument").field("version"))
|
|
@@ -275,12 +269,12 @@ extend self: Handler {
|
|
|
275
269
|
|
|
276
270
|
handleWorkspaceSymbol(system: NodeSystem, parameters: Map[String, Json]): ResultOrError {
|
|
277
271
|
let query = parameters.grab("query").grabString()
|
|
278
|
-
let files = self.printTime(system.mainTask(), "findFireflyFiles") {Builder.findFireflyFiles(self.rootPath.grab())}
|
|
272
|
+
let files = self.printTime(system.mainTask(), "findFireflyFiles") {Builder.findFireflyFiles(self.rootPath.grab(), None)}
|
|
279
273
|
let symbols = files.flatMap {file =>
|
|
280
274
|
let documentSymbols = self.getDocumentSymbolsWithCache(system, file)
|
|
281
275
|
let workspaceSymbols = documentSymbols.flatMap {SymbolHandler.documentToWorkspaceSymbols(_, None)}
|
|
282
276
|
if(query == "") {
|
|
283
|
-
workspaceSymbols.filter {_.kind ==
|
|
277
|
+
workspaceSymbols.filter {_.kind == SType}
|
|
284
278
|
} else {
|
|
285
279
|
workspaceSymbols.filter {SymbolHandler.symbolFilter(_, query)}
|
|
286
280
|
}
|
|
@@ -311,11 +305,10 @@ extend self: Handler {
|
|
|
311
305
|
|
|
312
306
|
handleHover(system: NodeSystem, targetAt: Location, goToDefinition: Bool): ResultOrError {
|
|
313
307
|
let lspHook = LspHook.make(at = Some(targetAt), definedAt = None, insertIdentifier = False, trackSymbols = False)
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
} catch {| CompileError(at, message), error =>
|
|
308
|
+
let errors = Builder.check(system, self.fireflyPath, system.path(targetAt.file), None, self.virtualFiles, lspHook, True)
|
|
309
|
+
errors.each {| CompileError(at, message) =>
|
|
317
310
|
Log.trace("handleHover check error: " + message)
|
|
318
|
-
}
|
|
311
|
+
}
|
|
319
312
|
let o = if(goToDefinition) {
|
|
320
313
|
HoverHandler.handleGoToDefinition(system, self, lspHook)
|
|
321
314
|
} else {
|
|
@@ -332,13 +325,11 @@ extend self: Handler {
|
|
|
332
325
|
line = token.startLine
|
|
333
326
|
column = token.startColumn
|
|
334
327
|
)
|
|
335
|
-
//Log.show(token.followedByLeftBracket)
|
|
336
328
|
let lspHook = LspHook.make(at = Some(completionAt), definedAt = None, insertIdentifier = True, trackSymbols = False)
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
} catch {| CompileError(at, message), error =>
|
|
329
|
+
let errors = Builder.check(system, self.fireflyPath, system.path(completionAt.file), None, self.virtualFiles, lspHook, True)
|
|
330
|
+
errors.each {| CompileError(at, message) =>
|
|
340
331
|
Log.trace("handleCompletion check error: " + message)
|
|
341
|
-
}
|
|
332
|
+
}
|
|
342
333
|
let o = CompletionHandler.handleCompletion(lspHook, completionAt.column == 1, token.followedByLeftBracket)
|
|
343
334
|
Result(o.write())
|
|
344
335
|
}
|
|
@@ -368,11 +359,10 @@ extend self: Handler {
|
|
|
368
359
|
Some(SignatureHelpHandler.pickActiveParameter(help, h.argumentIndex, h.parameterName))
|
|
369
360
|
| ParseArgumentHook h =>
|
|
370
361
|
let callLspHook = LspHook.make(at = Some(h.callAt), definedAt = None, insertIdentifier = False, trackSymbols = False)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
} catch {| CompileError(at, message), error =>
|
|
362
|
+
let errors = Builder.check(system, self.fireflyPath, system.path(cursorAt.file), None, self.virtualFiles, callLspHook, True)
|
|
363
|
+
errors.each {| CompileError(at, message) =>
|
|
374
364
|
Log.trace("handleSignatureHelp check 2 error: " + message)
|
|
375
|
-
}
|
|
365
|
+
}
|
|
376
366
|
let help = SignatureHelpHandler.handleSignatureHelp(system, callLspHook)
|
|
377
367
|
if(!help.isNull()) {
|
|
378
368
|
SignatureHelpHandler.pickActiveParameter(help, h.argumentIndex, h.parameterName)
|
|
@@ -427,40 +417,46 @@ extend self: Handler {
|
|
|
427
417
|
|
|
428
418
|
findReferences(system: NodeSystem, targetAt: Location, local: Bool, includeDeclaration: Bool): Option[List[TokenLocation]] {
|
|
429
419
|
let temporaryLspHook = LspHook.make(at = Some(targetAt), definedAt = None, insertIdentifier = False, trackSymbols = False)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
420
|
+
let errors = Builder.check(system, self.fireflyPath, system.path(targetAt.file), None, self.virtualFiles, temporaryLspHook, True)
|
|
421
|
+
errors.each {| CompileError(at, message) =>
|
|
422
|
+
Log.trace("findReferences first check error: " + message + " in " + at.file + ":" + at.line + ":" + at.column)
|
|
423
|
+
}
|
|
424
|
+
|
|
436
425
|
//Log.trace("defined at hooks: " + Show.show(temporaryLspHook.results().map(LspHook.showHook)))
|
|
437
426
|
let definedAtList = temporaryLspHook.results().collect {
|
|
438
|
-
| ResolveSymbolHook h => Some(h.symbol.definedAt)
|
|
439
|
-
| ResolveVariantFieldHook h => Some(h.symbol.definedAt)
|
|
440
|
-
| ResolveTypeHook h => Some(h.symbol.definedAt)
|
|
441
|
-
| ResolveConstraintHook h => Some(h.symbol.definedAt)
|
|
442
|
-
| ResolveSignatureHook h {!h.isInstanceMethod} => Some(h.signature.at)
|
|
443
|
-
| InferParameterHook h => Some(h.parameter.at)
|
|
427
|
+
| ResolveSymbolHook h => Some(Definition(h.symbol.definedAt, h.symbol.qualifiedName, local = !h.topLevel))
|
|
428
|
+
| ResolveVariantFieldHook h => Some(Definition(h.symbol.definedAt, h.symbol.qualifiedName, False))
|
|
429
|
+
| ResolveTypeHook h => Some(Definition(h.symbol.definedAt, h.symbol.qualifiedName, False))
|
|
430
|
+
| ResolveConstraintHook h => Some(Definition(h.symbol.definedAt, h.symbol.qualifiedName, False))
|
|
431
|
+
| ResolveSignatureHook h {!h.isInstanceMethod} => Some(Definition(h.signature.at, h.signature.name, local = !h.topLevel))
|
|
432
|
+
| InferParameterHook h => Some(Definition(h.parameter.at, h.parameter.name, False))
|
|
444
433
|
| InferArgumentHook h {h.arguments.dropFirst(h.argumentIndex).first() | Some(a)} {a.name | Some(n)} =>
|
|
445
|
-
h.parameters.find {_.name == n}.map {_.at}
|
|
446
|
-
| InferLookupHook h => Some(h.symbol.value.definedAt)
|
|
447
|
-
| InferPatternHook h {h.pattern | PVariantAs p} => Some(p.variableAt)
|
|
448
|
-
| InferPatternHook h {h.pattern | PVariable p} =>
|
|
449
|
-
| InferPatternHook h {h.pattern | PAlias p} => Some(p.at)
|
|
434
|
+
h.parameters.find {_.name == n}.map {Definition(_.at, n, False)}
|
|
435
|
+
| InferLookupHook h => Some(Definition(h.symbol.value.definedAt, h.symbol.value.qualifiedName, False))
|
|
436
|
+
| InferPatternHook h {h.pattern | PVariantAs p} => Some(Definition(p.variableAt, p.name, False))
|
|
437
|
+
| InferPatternHook h {h.pattern | PVariable p} => p.name.map {Definition(p.at, _, False)}
|
|
438
|
+
| InferPatternHook h {h.pattern | PAlias p} => Some(Definition(p.at, p.variable, False))
|
|
450
439
|
| _ => None
|
|
451
|
-
}.filter {
|
|
440
|
+
}.filter {pair => !pair.at.file.endsWith(">")}
|
|
452
441
|
|
|
442
|
+
function unqualify(qualifiedName: String): String {
|
|
443
|
+
qualifiedName.split('.').grabLast()
|
|
444
|
+
}
|
|
445
|
+
|
|
453
446
|
definedAtList.first().{
|
|
454
|
-
| Some(
|
|
447
|
+
| Some(definition) =>
|
|
455
448
|
//Log.trace("handleReferences definedAt: " + Show.show(definedAt))
|
|
456
|
-
let lspHook = LspHook.make(at = None, definedAt = Some(
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
449
|
+
let lspHook = LspHook.make(at = None, definedAt = Some(definition.at), insertIdentifier = False, trackSymbols = False)
|
|
450
|
+
let localCheck = local || definition.local
|
|
451
|
+
let path = if(localCheck) {system.path(targetAt.file)} else {self.rootPath.grab()}
|
|
452
|
+
let mustContain = Some(definition.name).filter {_ => !localCheck}.map(unqualify)
|
|
453
|
+
Log.trace("findReferences definition: " + Show.show(definition))
|
|
454
|
+
mustContain.each {Log.trace("mustContain: " + _)}
|
|
455
|
+
|
|
456
|
+
let errors = Builder.check(system, self.fireflyPath, path, mustContain, self.virtualFiles, lspHook, True)
|
|
457
|
+
errors.each {| CompileError(at, message) =>
|
|
458
|
+
Log.trace("findReferences second check error: " + message + " in " + at.file + ":" + at.line + ":" + at.column)
|
|
459
|
+
}
|
|
464
460
|
|
|
465
461
|
let referencesResult = lspHook.results().collect {
|
|
466
462
|
| ResolveSymbolHook h => Some(h.symbol.usageAt)
|
|
@@ -475,11 +471,11 @@ extend self: Handler {
|
|
|
475
471
|
| _ => None
|
|
476
472
|
}.filter {at =>
|
|
477
473
|
!at.file.endsWith(">") &&
|
|
478
|
-
(includeDeclaration || at !=
|
|
474
|
+
(includeDeclaration || at != definition.at)
|
|
479
475
|
}
|
|
480
476
|
|
|
481
477
|
let clientLocations = referencesResult.addAll(
|
|
482
|
-
if(includeDeclaration) {[
|
|
478
|
+
if(includeDeclaration) {[definition.at]} else {[]}
|
|
483
479
|
).distinct().filter {
|
|
484
480
|
!local || _.file == targetAt.file
|
|
485
481
|
}.map {at =>
|