firefly-compiler 0.4.20 → 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 (62) hide show
  1. package/compiler/Builder.ff +23 -13
  2. package/compiler/JsEmitter.ff +120 -76
  3. package/compiler/LspHook.ff +4 -2
  4. package/compiler/Main.ff +13 -7
  5. package/compiler/Resolver.ff +15 -15
  6. package/compiler/Syntax.ff +1 -0
  7. package/core/Array.ff +6 -4
  8. package/core/Int.ff +12 -12
  9. package/core/List.ff +6 -4
  10. package/experimental/benchmarks/ListGrab.ff +23 -0
  11. package/experimental/benchmarks/ListGrab.java +55 -0
  12. package/experimental/benchmarks/Pyrotek45.ff +30 -0
  13. package/experimental/benchmarks/Pyrotek45.java +64 -0
  14. package/experimental/tests/TestJson.ff +26 -0
  15. package/lsp/Handler.ff +55 -59
  16. package/lsp/SignatureHelpHandler.ff +5 -4
  17. package/lsp/TestReferences.ff +15 -0
  18. package/lsp/TestReferencesCase.ff +8 -0
  19. package/output/js/ff/compiler/Builder.mjs +50 -44
  20. package/output/js/ff/compiler/Dependencies.mjs +0 -2
  21. package/output/js/ff/compiler/Deriver.mjs +16 -140
  22. package/output/js/ff/compiler/Dictionaries.mjs +8 -222
  23. package/output/js/ff/compiler/Environment.mjs +12 -154
  24. package/output/js/ff/compiler/Inference.mjs +127 -1013
  25. package/output/js/ff/compiler/JsEmitter.mjs +434 -2344
  26. package/output/js/ff/compiler/JsImporter.mjs +0 -12
  27. package/output/js/ff/compiler/LspHook.mjs +20 -446
  28. package/output/js/ff/compiler/Main.mjs +96 -550
  29. package/output/js/ff/compiler/Parser.mjs +36 -356
  30. package/output/js/ff/compiler/Patterns.mjs +20 -200
  31. package/output/js/ff/compiler/Resolver.mjs +26 -340
  32. package/output/js/ff/compiler/Substitution.mjs +2 -160
  33. package/output/js/ff/compiler/Syntax.mjs +449 -3293
  34. package/output/js/ff/compiler/Token.mjs +9 -1095
  35. package/output/js/ff/compiler/Tokenizer.mjs +4 -2
  36. package/output/js/ff/compiler/Unification.mjs +26 -360
  37. package/output/js/ff/compiler/Wildcards.mjs +0 -86
  38. package/output/js/ff/compiler/Workspace.mjs +8 -96
  39. package/output/js/ff/core/Array.mjs +15 -8
  40. package/output/js/ff/core/AssetSystem.mjs +4 -14
  41. package/output/js/ff/core/Bool.mjs +0 -12
  42. package/output/js/ff/core/Core.mjs +0 -30
  43. package/output/js/ff/core/Int.mjs +24 -24
  44. package/output/js/ff/core/IntMap.mjs +0 -8
  45. package/output/js/ff/core/Json.mjs +0 -40
  46. package/output/js/ff/core/List.mjs +23 -32
  47. package/output/js/ff/core/Lock.mjs +0 -10
  48. package/output/js/ff/core/Map.mjs +0 -24
  49. package/output/js/ff/core/Option.mjs +10 -286
  50. package/output/js/ff/core/Ordering.mjs +16 -158
  51. package/output/js/ff/core/Pair.mjs +2 -34
  52. package/output/js/ff/core/Path.mjs +2 -28
  53. package/output/js/ff/core/Random.mjs +4 -4
  54. package/output/js/ff/core/RbMap.mjs +56 -644
  55. package/output/js/ff/core/Show.mjs +0 -16
  56. package/output/js/ff/core/Stream.mjs +14 -144
  57. package/output/js/ff/core/StringMap.mjs +0 -8
  58. package/output/js/ff/core/Try.mjs +4 -108
  59. package/output/js/ff/core/Unit.mjs +2 -16
  60. package/package.json +1 -1
  61. package/postgresql/Pg.ff +23 -23
  62. package/vscode/package.json +1 -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
+ }
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,7 +269,7 @@ 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)}
@@ -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 =>
@@ -44,10 +44,11 @@ handleSignatureHelp(system: NodeSystem, lspHook: LspHook): Json {
44
44
 
45
45
  pickActiveParameter(help: Json, argumentIndex: Int, parameterName: Option[String]): Json {
46
46
  parameterName.flatMap {name =>
47
- let parameters = help.field("signatures").index(0).field("parameters").grabArray()
48
- parameters.pairs().collectFirst {| Pair(i, p) =>
49
- if(name == p.field("label").grabString().takeWhile {_.isAsciiLetterOrDigit()}) {
50
- help.with("activeParameter", i)
47
+ help.field("signatures").index(0).field("parameters").getArray().flatMap {parameters =>
48
+ parameters.pairs().collectFirst {| Pair(i, p) =>
49
+ if(name == p.field("label").grabString().takeWhile {_.isAsciiLetterOrDigit()}) {
50
+ help.with("activeParameter", i)
51
+ }
51
52
  }
52
53
  }
53
54
  }.else {help.with("activeParameter", argumentIndex)}
@@ -0,0 +1,15 @@
1
+ import Handler
2
+ import Syntax from ff:compiler
3
+
4
+ nodeMain(system: NodeSystem) {
5
+ Log.debug("Hello")
6
+ let fireflyPath = system.path(".")
7
+ Log.debug(fireflyPath.absolute())
8
+ let handler = Handler(fireflyPath, None, Map.empty(), [].toSet(), Map.empty(), Map.empty())
9
+ let targetAt = Location("/home/werk/projects/firefly-boot/lsp/TestReferencesCase.ff", 7, 5)
10
+ let references = handler.findReferences(system, targetAt, local = False, includeDeclaration = True)
11
+ Log.show(references)
12
+ references.each {_.each {r =>
13
+ Log.show(r)
14
+ }}
15
+ }
@@ -0,0 +1,8 @@
1
+ foo(a: Int): Int {
2
+ a + a
3
+ }
4
+
5
+ nodeMain(system: NodeSystem) {
6
+ foo(13)
7
+ foo(37)
8
+ }
@@ -166,30 +166,19 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
166
166
  }))(resolvedDependencies_), ff_core_Option.None(), ff_core_NodeSystem.NodeSystem_path(system_, ".firefly/temporary"), ff_core_Path.Path_slash(ff_core_NodeSystem.NodeSystem_path(system_, ".firefly/output"), target_), false)
167
167
  }
168
168
 
169
- export function check_(system_, fireflyPath_, path_, virtualFiles_, lspHook_, infer_) {
169
+ export function check_(system_, fireflyPath_, path_, mustContain_, virtualFiles_, lspHook_, infer_) {
170
170
  const packages_ = (((_1) => {
171
- {
172
171
  if(_1) {
173
- return ff_compiler_Builder.findPackageFiles_(path_)
174
- return
175
- }
172
+ return ff_compiler_Builder.findPackageFiles_(path_, mustContain_)
176
173
  }
177
- {
178
- if(!_1) {
179
- const _guard1 = ff_core_Path.Path_endsWith(path_, [".firefly", "package.ff"]);
180
- if(_guard1) {
174
+ if(!_1 && ff_core_Path.Path_endsWith(path_, [".firefly", "package.ff"])) {
181
175
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab(ff_core_Path.Path_parent(path_)), ff_core_Option.Some(path_), [])]
182
- return
183
- }
184
176
  }
185
- }
186
- {
187
177
  if(!_1) {
188
178
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab(ff_core_Path.Path_parent(path_)), ff_core_Option.None(), [path_])]
189
- return
190
- }
191
179
  }
192
180
  }))(ff_core_Path.Path_isDirectory(path_));
181
+ const errors_ = ff_core_Array.make_();
193
182
  ff_core_List.List_each(ff_core_List.List_filter(packages_, ((_w1) => {
194
183
  return (!ff_core_List.List_isEmpty(_w1.files_))
195
184
  })), ((package_) => {
@@ -204,17 +193,29 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
204
193
  const compiler_ = ff_compiler_Compiler.make_(ff_compiler_JsEmitter.EmitBuild(), ff_core_NodeSystem.NodeSystem_mainTask(system_), ff_core_Option.None(), ff_core_Path.Path_slash(ff_core_Path.Path_slash(package_.root_, ".firefly"), "temporary"), fixedResolvedDependencies_, virtualFiles_, lspHook_);
205
194
  ff_core_List.List_each(package_.files_, ((file_) => {
206
195
  const localFile_ = ff_core_Path.Path_base(file_);
196
+ try {
207
197
  if(infer_) {
208
198
  ff_compiler_Compiler.Compiler_infer(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ff_core_String.String_size(".ff")))
209
199
  } else {
210
200
  ff_compiler_Compiler.Compiler_resolve(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ff_core_String.String_size(".ff")))
211
201
  }
202
+ } catch(_error) {
203
+ if(!_error.ffException) throw _error
204
+ const _exception = ff_core_Any.fromAny_(_error.ffException, ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)
205
+ if(!_exception.Some) throw _error
206
+ {
207
+ const c_ = _exception.value_;
208
+ const error_ = _error;
209
+ ff_core_Array.Array_push(errors_, c_)
210
+ }
211
+ }
212
212
  }))
213
- }))
213
+ }));
214
+ return ff_core_Array.Array_drain(errors_)
214
215
  }
215
216
 
216
- export function findPackageFiles_(path_) {
217
- const files_ = ff_compiler_Builder.findFireflyFiles_(path_);
217
+ export function findPackageFiles_(path_, mustContain_) {
218
+ const files_ = ff_compiler_Builder.findFireflyFiles_(path_, mustContain_);
218
219
  const split_ = ff_core_List.List_partition(files_, ((_w1) => {
219
220
  return ff_core_Path.Path_endsWith(_w1, [".firefly", "package.ff"])
220
221
  }));
@@ -235,7 +236,7 @@ return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.None(), [fi
235
236
  return [...multiFileProjects_, ...singleFileProjects_]
236
237
  }
237
238
 
238
- export function findFireflyFiles_(path_) {
239
+ export function findFireflyFiles_(path_, mustContain_) {
239
240
  const split_ = ff_core_List.List_partition(ff_core_Stream.Stream_toList(ff_core_Path.Path_entries(path_)), ((_w1) => {
240
241
  return ff_core_Path.PathEntry_isDirectory(_w1)
241
242
  }));
@@ -248,11 +249,13 @@ return (((c_ === 46) || ff_core_Char.Char_isAsciiLower(c_)) || ff_core_Char.Char
248
249
  }));
249
250
  const fireflyFiles_ = ff_core_List.List_filter(ff_core_List.List_map(split_.second_, ((_w1) => {
250
251
  return ff_core_Path.PathEntry_path(_w1)
251
- })), ((_w1) => {
252
- return (ff_core_Path.Path_extension(_w1) === ".ff")
252
+ })), ((file_) => {
253
+ return ((ff_core_Path.Path_extension(file_) === ".ff") && ff_core_Option.Option_all(mustContain_, ((s_) => {
254
+ return ff_core_String.String_contains(ff_core_Path.Path_readText(file_), s_)
255
+ })))
253
256
  }));
254
257
  return [...fireflyFiles_, ...ff_core_List.List_flatMap(directories_, ((_w1) => {
255
- return ff_compiler_Builder.findFireflyFiles_(_w1)
258
+ return ff_compiler_Builder.findFireflyFiles_(_w1, mustContain_)
256
259
  }))]
257
260
  }
258
261
 
@@ -345,30 +348,19 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
345
348
  }))(resolvedDependencies_), ff_core_Option.None(), (await ff_core_NodeSystem.NodeSystem_path$(system_, ".firefly/temporary", $task)), (await ff_core_Path.Path_slash$((await ff_core_NodeSystem.NodeSystem_path$(system_, ".firefly/output", $task)), target_, $task)), false, $task))
346
349
  }
347
350
 
348
- export async function check_$(system_, fireflyPath_, path_, virtualFiles_, lspHook_, infer_, $task) {
351
+ export async function check_$(system_, fireflyPath_, path_, mustContain_, virtualFiles_, lspHook_, infer_, $task) {
349
352
  const packages_ = (await ((async (_1, $task) => {
350
- {
351
353
  if(_1) {
352
- return (await ff_compiler_Builder.findPackageFiles_$(path_, $task))
353
- return
354
- }
354
+ return (await ff_compiler_Builder.findPackageFiles_$(path_, mustContain_, $task))
355
355
  }
356
- {
357
- if(!_1) {
358
- const _guard1 = (await ff_core_Path.Path_endsWith$(path_, [".firefly", "package.ff"], $task));
359
- if(_guard1) {
356
+ if(!_1 && (await ff_core_Path.Path_endsWith$(path_, [".firefly", "package.ff"], $task))) {
360
357
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(path_, $task))), ff_core_Option.Some(path_), [])]
361
- return
362
- }
363
358
  }
364
- }
365
- {
366
359
  if(!_1) {
367
360
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(path_, $task))), ff_core_Option.None(), [path_])]
368
- return
369
- }
370
361
  }
371
362
  }))((await ff_core_Path.Path_isDirectory$(path_, $task)), $task));
363
+ const errors_ = ff_core_Array.make_();
372
364
  (await ff_core_List.List_each$(ff_core_List.List_filter(packages_, ((_w1) => {
373
365
  return (!ff_core_List.List_isEmpty(_w1.files_))
374
366
  })), (async (package_, $task) => {
@@ -383,17 +375,29 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
383
375
  const compiler_ = (await ff_compiler_Compiler.make_$(ff_compiler_JsEmitter.EmitBuild(), (await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), ff_core_Option.None(), (await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$(package_.root_, ".firefly", $task)), "temporary", $task)), fixedResolvedDependencies_, virtualFiles_, lspHook_, $task));
384
376
  (await ff_core_List.List_each$(package_.files_, (async (file_, $task) => {
385
377
  const localFile_ = (await ff_core_Path.Path_base$(file_, $task));
378
+ try {
386
379
  if(infer_) {
387
380
  (await ff_compiler_Compiler.Compiler_infer$(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ff_core_String.String_size(".ff")), $task))
388
381
  } else {
389
382
  (await ff_compiler_Compiler.Compiler_resolve$(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ff_core_String.String_size(".ff")), $task))
390
383
  }
384
+ } catch(_error) {
385
+ if(!_error.ffException) throw _error
386
+ const _exception = ff_core_Any.fromAny_(_error.ffException, ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)
387
+ if(!_exception.Some) throw _error
388
+ {
389
+ const c_ = _exception.value_;
390
+ const error_ = _error;
391
+ ff_core_Array.Array_push(errors_, c_)
392
+ }
393
+ }
391
394
  }), $task))
392
- }), $task))
395
+ }), $task));
396
+ return ff_core_Array.Array_drain(errors_)
393
397
  }
394
398
 
395
- export async function findPackageFiles_$(path_, $task) {
396
- const files_ = (await ff_compiler_Builder.findFireflyFiles_$(path_, $task));
399
+ export async function findPackageFiles_$(path_, mustContain_, $task) {
400
+ const files_ = (await ff_compiler_Builder.findFireflyFiles_$(path_, mustContain_, $task));
397
401
  const split_ = (await ff_core_List.List_partition$(files_, (async (_w1, $task) => {
398
402
  return (await ff_core_Path.Path_endsWith$(_w1, [".firefly", "package.ff"], $task))
399
403
  }), $task));
@@ -414,7 +418,7 @@ return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.None(), [fi
414
418
  return [...multiFileProjects_, ...singleFileProjects_]
415
419
  }
416
420
 
417
- export async function findFireflyFiles_$(path_, $task) {
421
+ export async function findFireflyFiles_$(path_, mustContain_, $task) {
418
422
  const split_ = (await ff_core_List.List_partition$((await ff_core_Stream.Stream_toList$((await ff_core_Path.Path_entries$(path_, $task)), $task)), (async (_w1, $task) => {
419
423
  return (await ff_core_Path.PathEntry_isDirectory$(_w1, $task))
420
424
  }), $task));
@@ -427,11 +431,13 @@ return (((c_ === 46) || ff_core_Char.Char_isAsciiLower(c_)) || ff_core_Char.Char
427
431
  }), $task));
428
432
  const fireflyFiles_ = (await ff_core_List.List_filter$((await ff_core_List.List_map$(split_.second_, (async (_w1, $task) => {
429
433
  return (await ff_core_Path.PathEntry_path$(_w1, $task))
430
- }), $task)), (async (_w1, $task) => {
431
- return ((await ff_core_Path.Path_extension$(_w1, $task)) === ".ff")
434
+ }), $task)), (async (file_, $task) => {
435
+ return (((await ff_core_Path.Path_extension$(file_, $task)) === ".ff") && (await ff_core_Option.Option_all$(mustContain_, (async (s_, $task) => {
436
+ return ff_core_String.String_contains((await ff_core_Path.Path_readText$(file_, $task)), s_)
437
+ }), $task)))
432
438
  }), $task));
433
439
  return [...fireflyFiles_, ...(await ff_core_List.List_flatMap$(directories_, (async (_w1, $task) => {
434
- return (await ff_compiler_Builder.findFireflyFiles_$(_w1, $task))
440
+ return (await ff_compiler_Builder.findFireflyFiles_$(_w1, mustContain_, $task))
435
441
  }), $task))]
436
442
  }
437
443