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.
Files changed (68) hide show
  1. package/compiler/Builder.ff +23 -13
  2. package/compiler/JsEmitter.ff +120 -76
  3. package/compiler/LspHook.ff +17 -3
  4. package/compiler/Main.ff +13 -7
  5. package/compiler/Parser.ff +11 -13
  6. package/compiler/Resolver.ff +15 -15
  7. package/compiler/Syntax.ff +1 -0
  8. package/core/Array.ff +6 -4
  9. package/core/Int.ff +12 -12
  10. package/core/Json.ff +2 -2
  11. package/core/List.ff +6 -4
  12. package/experimental/benchmarks/ListGrab.ff +23 -0
  13. package/experimental/benchmarks/ListGrab.java +55 -0
  14. package/experimental/benchmarks/Pyrotek45.ff +30 -0
  15. package/experimental/benchmarks/Pyrotek45.java +64 -0
  16. package/experimental/tests/TestJson.ff +26 -0
  17. package/lsp/CompletionHandler.ff +14 -14
  18. package/lsp/Handler.ff +56 -60
  19. package/lsp/SignatureHelpHandler.ff +5 -4
  20. package/lsp/SymbolHandler.ff +18 -4
  21. package/lsp/TestReferences.ff +15 -0
  22. package/lsp/TestReferencesCase.ff +8 -0
  23. package/output/js/ff/compiler/Builder.mjs +50 -44
  24. package/output/js/ff/compiler/Dependencies.mjs +0 -2
  25. package/output/js/ff/compiler/Deriver.mjs +16 -140
  26. package/output/js/ff/compiler/Dictionaries.mjs +8 -222
  27. package/output/js/ff/compiler/Environment.mjs +12 -154
  28. package/output/js/ff/compiler/Inference.mjs +127 -1013
  29. package/output/js/ff/compiler/JsEmitter.mjs +434 -2344
  30. package/output/js/ff/compiler/JsImporter.mjs +0 -12
  31. package/output/js/ff/compiler/LspHook.mjs +548 -151
  32. package/output/js/ff/compiler/Main.mjs +96 -550
  33. package/output/js/ff/compiler/Parser.mjs +58 -390
  34. package/output/js/ff/compiler/Patterns.mjs +20 -200
  35. package/output/js/ff/compiler/Resolver.mjs +26 -340
  36. package/output/js/ff/compiler/Substitution.mjs +2 -160
  37. package/output/js/ff/compiler/Syntax.mjs +449 -3293
  38. package/output/js/ff/compiler/Token.mjs +9 -1095
  39. package/output/js/ff/compiler/Tokenizer.mjs +4 -2
  40. package/output/js/ff/compiler/Unification.mjs +26 -360
  41. package/output/js/ff/compiler/Wildcards.mjs +0 -86
  42. package/output/js/ff/compiler/Workspace.mjs +8 -96
  43. package/output/js/ff/core/Array.mjs +15 -8
  44. package/output/js/ff/core/AssetSystem.mjs +4 -14
  45. package/output/js/ff/core/Bool.mjs +0 -12
  46. package/output/js/ff/core/Core.mjs +0 -30
  47. package/output/js/ff/core/Int.mjs +24 -24
  48. package/output/js/ff/core/IntMap.mjs +0 -8
  49. package/output/js/ff/core/Json.mjs +2 -42
  50. package/output/js/ff/core/List.mjs +23 -32
  51. package/output/js/ff/core/Lock.mjs +0 -10
  52. package/output/js/ff/core/Map.mjs +0 -24
  53. package/output/js/ff/core/Option.mjs +10 -286
  54. package/output/js/ff/core/Ordering.mjs +16 -158
  55. package/output/js/ff/core/Pair.mjs +2 -34
  56. package/output/js/ff/core/Path.mjs +2 -28
  57. package/output/js/ff/core/Random.mjs +4 -4
  58. package/output/js/ff/core/RbMap.mjs +56 -644
  59. package/output/js/ff/core/Show.mjs +0 -16
  60. package/output/js/ff/core/Stream.mjs +14 -144
  61. package/output/js/ff/core/StringMap.mjs +0 -8
  62. package/output/js/ff/core/Try.mjs +4 -108
  63. package/output/js/ff/core/Unit.mjs +2 -16
  64. package/package.json +1 -1
  65. package/postgresql/Pg.ff +23 -23
  66. package/vscode/client/src/extension.ts +30 -2
  67. package/vscode/package.json +17 -1
  68. package/core/Stack.ff +0 -250
@@ -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 { _ != '/' }.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 { 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) }
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) {
@@ -9,6 +9,7 @@ extend self: Location {
9
9
  }
10
10
 
11
11
  data CompileError(at: Location, message: String)
12
+ data CompileErrors(errors: List[CompileError])
12
13
 
13
14
  data ModuleWithPackageInfo(
14
15
  packageInfo: Option[PackageInfo]
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
- if(index_ < 0 || index_ >= self_.array.length) {
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
- mutable result = []
31
- mutable n = inclusiveEnd
32
- while {self <= n} {
33
- result = [n, ...result]
34
- n -= 1
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
- mutable result = []
41
- mutable n = exclusiveEnd
42
- while {self < n} {
43
- result = [n - 1, ...result]
44
- n -= 1
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(isNaB(a_)) return isNaB(b_) ? 0 : -1;
409
- if(isNaB(b_)) return 1;
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
- if(index_ < 0 || index_ >= self_.length) {
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
+ }
@@ -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:httpserver:0.0.0"
752
- "import HttpServer from ff:httpserver"
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
- " HttpServer.listen(system, \"localhost\", 8080) {request, response =>"
762
- " if(request.path() == \"/\") {"
763
- " response.setHeader(\"Content-Type\", [\"text/html; charset=UTF-8\"])"
764
- " response.writeText(\"<!doctype html>\")"
765
- " response.writeText(\"<script type='module' src='/js/script/script/WebApp.mjs'></script>\")"
766
- " } elseIf {request.path() == \"/hello\"} {"
767
- " response.setHeader(\"Content-Type\", [\"text/plain; charset=UTF-8\"])"
768
- " response.writeText(\"Hello from server!\")"
769
- " } elseIf {request.path().startsWith(\"/js/\") && !request.path().contains(\"..\")} {"
770
- " response.setHeader(\"Content-Type\", [\"text/javascript; charset=UTF-8\"])"
771
- " response.writeText(system.assets().readText(request.path()))"
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
- " response.writeStatus(404, Some(\"Not found\"))"
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 diagnostics = try {
198
- Builder.check(system, fireflyPath, path, self.virtualFiles, LspHook.disabled(), True)
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
- let diagnostic = Json.object()
202
+ Json.object()
203
203
  .with("range", self.tokenLocationToLspRange(tokenLocation))
204
204
  .with("severity", 1)
205
205
  .with("message", message)
206
- [diagnostic]
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 diagnostics = try {
221
- Builder.check(system, fireflyPath, path, self.virtualFiles, LspHook.disabled(), True)
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
- let diagnostic = Json.object()
221
+ Json.object()
226
222
  .with("range", self.tokenLocationToLspRange(tokenLocation))
227
223
  .with("severity", 1)
228
224
  .with("message", message)
229
- [diagnostic].filter {_ => path.absolute() == system.path(at.file).absolute()}
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 == 5} // Class
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
- try {
315
- Builder.check(system, self.fireflyPath, system.path(targetAt.file), self.virtualFiles, lspHook, True)
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
- } grab()
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
- try {
338
- Builder.check(system, self.fireflyPath, system.path(completionAt.file), self.virtualFiles, lspHook, True)
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
- } grab()
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
- try {
372
- Builder.check(system, self.fireflyPath, system.path(cursorAt.file), self.virtualFiles, callLspHook, True)
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
- } grab()
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
- try {
431
- Builder.check(system, self.fireflyPath, system.path(targetAt.file), self.virtualFiles, temporaryLspHook, True)
432
- } catch {| CompileError(at, message), error =>
433
- Log.trace("findReferences first check error: " + message)
434
- } grab()
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} => Some(p.at)
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 {at => !at.file.endsWith(">")}
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(definedAt) =>
447
+ | Some(definition) =>
455
448
  //Log.trace("handleReferences definedAt: " + Show.show(definedAt))
456
- let lspHook = LspHook.make(at = None, definedAt = Some(definedAt), insertIdentifier = False, trackSymbols = False)
457
- try {
458
- let path = if(local) {system.path(targetAt.file)} else {self.rootPath.grab()}
459
- Builder.check(system, self.fireflyPath, path, self.virtualFiles, lspHook, True)
460
- } catch {| CompileError(at, message), error =>
461
- // TODO: This skips checking all the other files
462
- Log.trace("findReferences second check error: " + message)
463
- } grab()
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 != definedAt)
474
+ (includeDeclaration || at != definition.at)
479
475
  }
480
476
 
481
477
  let clientLocations = referencesResult.addAll(
482
- if(includeDeclaration) {[definedAt]} else {[]}
478
+ if(includeDeclaration) {[definition.at]} else {[]}
483
479
  ).distinct().filter {
484
480
  !local || _.file == targetAt.file
485
481
  }.map {at =>