firefly-compiler 0.5.63 → 0.5.65

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 (59) hide show
  1. package/compiler/Builder.ff +47 -31
  2. package/compiler/Compiler.ff +42 -47
  3. package/compiler/Dependencies.ff +9 -3
  4. package/compiler/Deriver.ff +2 -2
  5. package/compiler/Dictionaries.ff +11 -12
  6. package/compiler/Environment.ff +5 -5
  7. package/compiler/Inference.ff +1 -2
  8. package/compiler/JsEmitter.ff +34 -33
  9. package/compiler/Main.ff +32 -31
  10. package/compiler/ModuleCache.ff +17 -25
  11. package/compiler/Parser.ff +7 -11
  12. package/compiler/Resolver.ff +8 -11
  13. package/compiler/Syntax.ff +53 -17
  14. package/compiler/Unification.ff +2 -5
  15. package/core/BuildSystem.ff +1 -1
  16. package/core/Path.ff +11 -1
  17. package/core/SourceLocation.ff +4 -0
  18. package/experimental/foldertest/.firefly/package.ff +1 -0
  19. package/experimental/foldertest/Root.ff +10 -0
  20. package/experimental/foldertest/a/A.ff +3 -0
  21. package/experimental/foldertest/a/MainA.ff +3 -0
  22. package/experimental/tests/TestCancel.ff +19 -0
  23. package/fireflysite/CommunityOverview.ff +0 -2
  24. package/fireflysite/FrontPage.ff +0 -2
  25. package/fireflysite/Main.ff +1 -1
  26. package/fireflysite/PackagesOverview.ff +0 -2
  27. package/fireflysite/Router.ff +3 -3
  28. package/fireflysite/{ExamplesOverview.ff → demos/ExamplesOverview.ff} +3 -3
  29. package/fireflysite/{RouteFront.ff → routes/RouteFront.ff} +2 -3
  30. package/fireflysite/{RouteNonMarkdown.ff → routes/RouteNonMarkdown.ff} +5 -5
  31. package/fireflysite/{RouteReference.ff → routes/RouteReference.ff} +2 -3
  32. package/lsp/CompletionHandler.ff +2 -2
  33. package/lsp/Handler.ff +14 -13
  34. package/lsp/LanguageServer.ff +5 -4
  35. package/output/js/ff/compiler/Builder.mjs +118 -80
  36. package/output/js/ff/compiler/Compiler.mjs +85 -89
  37. package/output/js/ff/compiler/Dependencies.mjs +16 -10
  38. package/output/js/ff/compiler/Deriver.mjs +6 -6
  39. package/output/js/ff/compiler/Dictionaries.mjs +6 -6
  40. package/output/js/ff/compiler/Environment.mjs +10 -6
  41. package/output/js/ff/compiler/Inference.mjs +4 -4
  42. package/output/js/ff/compiler/JsEmitter.mjs +60 -38
  43. package/output/js/ff/compiler/Main.mjs +66 -56
  44. package/output/js/ff/compiler/ModuleCache.mjs +34 -38
  45. package/output/js/ff/compiler/Parser.mjs +14 -14
  46. package/output/js/ff/compiler/Resolver.mjs +12 -22
  47. package/output/js/ff/compiler/Substitution.mjs +2 -2
  48. package/output/js/ff/compiler/Syntax.mjs +395 -183
  49. package/output/js/ff/compiler/Unification.mjs +18 -32
  50. package/output/js/ff/core/BuildSystem.mjs +2 -6
  51. package/output/js/ff/core/Path.mjs +32 -0
  52. package/output/js/ff/core/SourceLocation.mjs +12 -0
  53. package/package.json +1 -1
  54. package/vscode/package.json +1 -1
  55. package/vscode/syntaxes/firefly.tmLanguage.json +299 -299
  56. package/fireflysite/ReferenceIntroduction.ff +0 -11
  57. /package/fireflysite/{CountingButtonDemo.ff → demos/CountingButtonDemo.ff} +0 -0
  58. /package/fireflysite/{MatchingPasswordsDemo.ff → demos/MatchingPasswordsDemo.ff} +0 -0
  59. /package/fireflysite/{PostgresqlDemo.ff → demos/PostgresqlDemo.ff} +0 -0
@@ -1,8 +1,8 @@
1
1
  import WebServer from ff:webserver
2
2
  import WebRoute from ff:webserver
3
- import RouteFront
4
- import RouteReference
5
- import RouteNonMarkdown
3
+ import routes.RouteFront
4
+ import routes.RouteReference
5
+ import routes.RouteNonMarkdown
6
6
 
7
7
  capability RouteContext(system: NodeSystem)
8
8
 
@@ -1,7 +1,7 @@
1
1
  import Guide
2
- import CountingButtonDemo
3
- import MatchingPasswordsDemo
4
- import PostgresqlDemo
2
+ import demos.CountingButtonDemo
3
+ import demos.MatchingPasswordsDemo
4
+ import demos.PostgresqlDemo
5
5
 
6
6
  demos(): List[Demo] {
7
7
  [
@@ -2,13 +2,12 @@ import Lux from ff:lux
2
2
  import WebServer from ff:webserver
3
3
  import Router
4
4
  import Guide
5
- import ExamplesOverview
6
5
  import FrontPage
7
6
  import Html
8
7
  import Website
9
8
  import Menu
10
9
 
11
- routeModule = SourceLocation.here().module()
10
+ routeModule = SourceLocation.here().directoryAndModule()
12
11
 
13
12
  data PageData(sections: List[Section])
14
13
 
@@ -25,6 +24,6 @@ browserMain(system: BrowserSystem) {
25
24
  render(lux: Lux, data: PageData) {
26
25
  let next = None // TODO MenuItem(["getting-started"], Menu.menu.grabFirst().name, None)
27
26
  Website.renderContentWithNext(lux, [], next) {lux =>
28
- Guide.renderSections(lux, data.sections, ExamplesOverview.demos())
27
+ Guide.renderSections(lux, data.sections, [])
29
28
  }
30
29
  }
@@ -2,18 +2,18 @@ import Lux from ff:lux
2
2
  import WebServer from ff:webserver
3
3
  import Router
4
4
  import Guide
5
- import ExamplesOverview
5
+ import demos.ExamplesOverview
6
6
  import GettingStarted
7
- import CountingButtonDemo
8
- import MatchingPasswordsDemo
9
- import PostgresqlDemo
7
+ import demos.CountingButtonDemo
8
+ import demos.MatchingPasswordsDemo
9
+ import demos.PostgresqlDemo
10
10
  import Html
11
11
  import Website
12
12
  import Menu
13
13
  import PackagesOverview
14
14
  import CommunityOverview
15
15
 
16
- routeModule = SourceLocation.here().module()
16
+ routeModule = SourceLocation.here().directoryAndModule()
17
17
 
18
18
  data PageData(menuEntry: MenuItem, sections: List[Section])
19
19
 
@@ -2,14 +2,13 @@ import Lux from ff:lux
2
2
  import WebServer from ff:webserver
3
3
  import Router
4
4
  import Guide
5
- import ExamplesOverview
6
5
  import FrontPage
7
6
  import DocumentParser
8
7
  import Html
9
8
  import Website
10
9
  import Menu
11
10
 
12
- routeModule = SourceLocation.here().module()
11
+ routeModule = SourceLocation.here().directoryAndModule()
13
12
 
14
13
  data PageData(menuEntry: MenuItem, sections: List[Section])
15
14
 
@@ -35,6 +34,6 @@ browserMain(system: BrowserSystem) {
35
34
 
36
35
  render(lux: Lux, data: PageData) {
37
36
  Website.renderContentWithNext(lux, data.menuEntry.path, data.menuEntry.next) {lux =>
38
- Guide.renderSections(lux, data.sections, ExamplesOverview.demos())
37
+ Guide.renderSections(lux, data.sections, [])
39
38
  }
40
39
  }
@@ -250,10 +250,10 @@ completion(
250
250
  } else {
251
251
  let module = name.dropLast(shorter.size() + 1)
252
252
  let alias = environment.imports.find {_, i =>
253
- module == i.package.groupName() + "/" + i.directory.map {_ + "/"}.join() + i.file
253
+ module == i.moduleKey.qualifiedName()
254
254
  }
255
255
  alias.map {| Pair(alias, i) =>
256
- Pair(alias + short.dropFirst(i.file.size()), scheme)
256
+ Pair(alias + "." + shorter, scheme)
257
257
  }
258
258
  }
259
259
  | _ =>
package/lsp/Handler.ff CHANGED
@@ -273,7 +273,8 @@ extend self: Handler {
273
273
  let lspHook = LspHook.new(at = None, definedAt = None, insertIdentifier = False, trackSymbols = True)
274
274
  let code = self.virtualFiles.get(path.absolute()).else {path.readText()}
275
275
  let tokens = Tokenizer.tokenize(path.absolute(), code, None, True)
276
- let parser = Parser.new(PackagePair("script", "script"), path.absolute(), tokens, False, lspHook)
276
+ let dummyModuleKey = ModuleKey(PackagePair("script", "script"), [], path.base())
277
+ let parser = Parser.new(dummyModuleKey, tokens, False, lspHook)
277
278
  parser.parseModuleWithPackageInfo()
278
279
  SymbolHandler.readAllSymbols(lspHook.results())
279
280
  } tryCatch {| CompileError(at, message), error =>
@@ -368,6 +369,7 @@ extend self: Handler {
368
369
  let lspHook = LspHook.new(at = Some(targetAt), definedAt = None, insertIdentifier = False, trackSymbols = False)
369
370
  let path = system.path(targetAt.file)
370
371
  let errors = self.check(system, self.fireflyPath, path, None, Set.new(), self.virtualFiles, version, lspHook, True)
372
+ Log.trace("errors: " + Show.show(errors))
371
373
  errors.each {| CompileError(at, message) =>
372
374
  Log.trace("handleHover check error: " + message)
373
375
  }
@@ -403,7 +405,8 @@ extend self: Handler {
403
405
  try {
404
406
  let code = self.virtualFiles.get(cursorAt.file).else {system.path(cursorAt.file).readText()}
405
407
  let tokens = Tokenizer.tokenize(cursorAt.file, code, None, True)
406
- let parser = Parser.new(PackagePair("script", "script"), cursorAt.file, tokens, False, lspHook)
408
+ let dummyModuleKey = ModuleKey(PackagePair("script", "script"), [], "<LSP>")
409
+ let parser = Parser.new(dummyModuleKey, tokens, False, lspHook)
407
410
  parser.parseModuleWithPackageInfo()
408
411
  } tryCatch {| CompileError(at, message), error =>
409
412
  Log.trace("handleSignatureHelp check error: " + message)
@@ -521,14 +524,14 @@ extend self: Handler {
521
524
  qualifiedName.split('.').grabLast().split('_').grabLast()
522
525
  }
523
526
 
524
- function extractModuleName(qualifiedName: String): String {
525
- qualifiedName.split('/').grabLast().takeWhile {c => c != '.' || c == '_'}
526
- }
527
-
528
- function extractPackagePair(qualifiedName: String): PackagePair {
527
+ function extractModuleKey(qualifiedName: String): ModuleKey {
529
528
  let group = qualifiedName.split(':').grabFirst()
530
529
  let name = qualifiedName.split(':').grabLast().takeWhile {_ != '/'}
531
- PackagePair(group, name)
530
+ let packagePair = PackagePair(group, name)
531
+ let moduleParts = qualifiedName.split('/').dropFirst()
532
+ let moduleFolders = moduleParts.dropLast()
533
+ let moduleName = moduleParts.grabLast().takeWhile {c => c != '.' || c == '_'}
534
+ ModuleKey(packagePair, moduleFolders, moduleName)
532
535
  }
533
536
 
534
537
  definedAtList.first().{
@@ -541,18 +544,18 @@ extend self: Handler {
541
544
  mustContain.each {Log.trace("mustContain: " + _)}
542
545
 
543
546
  let skipFiles = if(definition.name.contains(":")) {
544
- let list = self.moduleCache.filesNotImporting(extractPackagePair(definition.name), extractModuleName(definition.name))
547
+ let list = self.moduleCache.filesNotImporting(extractModuleKey(definition.name))
545
548
  list.toSet()
546
549
  } else {
547
550
  self.moduleCache.parsedModules.get(definition.at.file).map {| Pair(module, _) =>
548
- let list = self.moduleCache.filesNotImporting(module.packagePair, module.file.dropLast(3))
551
+ let list = self.moduleCache.filesNotImporting(module.moduleKey)
549
552
  list.toSet()
550
553
  }.else {
551
554
  Log.trace("No skip list due to unqualified definition.name: " + definition.name)
552
555
  Set.new()
553
556
  }
554
557
  }
555
- let errors = self.check(system, self.fireflyPath, path, mustContain, skipFiles, self.virtualFiles, version, lspHook, True, False)
558
+ let errors = self.check(system, self.fireflyPath, path, mustContain, skipFiles, self.virtualFiles, version, lspHook, True)
556
559
  errors.each {| CompileError(at, message) =>
557
560
  Log.trace("findReferences second check error: " + message + " in " + at.file + ":" + at.line + ":" + at.column)
558
561
  }
@@ -698,7 +701,6 @@ extend self: Handler {
698
701
  newModuleCacheVersion: Int
699
702
  lspHook: LspHook
700
703
  infer: Bool
701
- checkDependencies: Bool = True
702
704
  ): List[CompileError] {
703
705
  Builder.check(
704
706
  system
@@ -712,7 +714,6 @@ extend self: Handler {
712
714
  newModuleCacheVersion
713
715
  lspHook
714
716
  infer
715
- checkDependencies
716
717
  )
717
718
  }
718
719
 
@@ -63,18 +63,19 @@ main(system: NodeSystem) {
63
63
  let message = parseRequestMessage(request.object)
64
64
  logDirectory.each {logMessage(_, "request", request.object, message.method)}
65
65
  spawn(message.id) {_ =>
66
- if(message.method == "$/cancelRequest") {
67
- abort(Some(parseMessageId(message.parameters.grab("id"))))
68
- }
69
66
  try {
67
+ if(message.method == "$/cancelRequest") {
68
+ abort(Some(parseMessageId(message.parameters.grab("id"))))
69
+ }
70
70
  handleRequestMessage(system, handler, message, version).each {body =>
71
71
  responseChannel.write(Pair(body, message.method))
72
72
  }
73
73
  } catchAny {error =>
74
74
  let problem = if(error.name() == "AbortError") {
75
+ Log.trace("LS ABORT")
75
76
  Error(-32800, "Request cancelled")
76
77
  } else {
77
- Log.trace("ERROR: " + error.message())
78
+ Log.trace("LS ERROR " + error.name() + ": " + error.message())
78
79
  Log.trace(error.stack())
79
80
  Error(-32603, "Internal error")
80
81
  }
@@ -125,7 +125,7 @@ return {root_, packageFile_, files_};
125
125
 
126
126
 
127
127
 
128
- export function build_(system_, emitTarget_, mainPackage_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_) {
128
+ export function build_(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_) {
129
129
  if(ff_core_Path.Path_exists(tempPath_, false, false, false)) {
130
130
  ff_core_Path.Path_delete(tempPath_, 0, 100)
131
131
  };
@@ -135,8 +135,8 @@ ff_core_Path.Path_createDirectory(jsPathFile_, true);
135
135
  const success_ = ff_core_Core.do_((() => {
136
136
  const compiler_ = ff_compiler_Compiler.new_(emitTarget_, ff_core_NodeSystem.NodeSystem_mainTask(system_), compilerModulePath_, jsPathFile_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_());
137
137
  for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
138
- const mainModule_ = for_a[for_i];
139
- ff_compiler_Compiler.Compiler_emit(compiler_, mainPackage_, mainModule_, true)
138
+ const moduleKey_ = for_a[for_i];
139
+ ff_compiler_Compiler.Compiler_emit(compiler_, moduleKey_, true)
140
140
  };
141
141
  if(printMeasurements_) {
142
142
  ff_compiler_Compiler.Compiler_printMeasurements(compiler_)
@@ -190,46 +190,41 @@ ff_core_NodeSystem.NodeSystem_writeErrorBuffer(system_, result_.standardError_)
190
190
  }
191
191
 
192
192
  export function buildViaBuildSystem_(system_, fireflyPath_, mainFiles_, target_) {
193
- const mainPaths_ = ff_core_List.List_map(mainFiles_, ((_w1) => {
194
- return ff_core_Path.Path_absolute(ff_core_Option.Option_grab(ff_core_Path.Path_parent(ff_core_NodeSystem.NodeSystem_path(system_, _w1))))
195
- }));
196
- {
197
- const if_o = ff_core_List.List_find(mainPaths_, ((_w1) => {
198
- return (_w1 !== ff_core_List.List_grabFirst(mainPaths_))
199
- }))
200
- if(if_o.Some) {
201
- const path_ = if_o.value_;
202
- ff_core_Core.panic_(((("Can't build multiple main files in different directories: " + path_) + " vs. ") + ff_core_List.List_grabFirst(mainPaths_)))
203
- }
204
- };
205
- const resolvedDependencies_ = ff_compiler_Dependencies.process_(ff_core_NodeSystem.NodeSystem_httpClient(system_), ff_compiler_DependencyLock.new_(ff_core_NodeSystem.NodeSystem_mainTask(system_)), ff_core_NodeSystem.NodeSystem_path(system_, ff_core_List.List_grabFirst(mainFiles_)));
193
+ const resolvedDependencies_ = ff_compiler_Dependencies.process_(ff_core_NodeSystem.NodeSystem_httpClient(system_), ff_compiler_DependencyLock.new_(ff_core_NodeSystem.NodeSystem_mainTask(system_)), ff_core_List.List_grabFirst(mainFiles_));
206
194
  const fixedPackagePaths_ = (ff_core_Map.Map_contains(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
207
195
  ? resolvedDependencies_.packagePaths_
208
196
  : ff_core_Map.Map_add(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_core_Path.Path_slash(fireflyPath_, "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair));
197
+ const packageRoot_ = ff_core_Map.Map_grab(resolvedDependencies_.packagePaths_, resolvedDependencies_.mainPackagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair);
198
+ const mainModuleKeys_ = ff_core_List.List_map(mainFiles_, ((mainFile_) => {
199
+ return ff_core_Option.Option_else(ff_compiler_Syntax.PackagePair_moduleKey(resolvedDependencies_.mainPackagePair_, packageRoot_, mainFile_), (() => {
200
+ return ff_core_Core.panic_(((("Can't build multiple main files in different packages: " + ff_core_Path.Path_absolute(mainFile_)) + " isn't part of ") + ff_core_Path.Path_absolute(packageRoot_)))
201
+ }))
202
+ }));
209
203
  if((target_ !== "browser")) {
210
204
  ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target only - the restriction can be lifted")
211
205
  };
212
- ff_compiler_Builder.build_(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_List.List_map(mainFiles_, ((_w1) => {
213
- return ff_core_String.String_dropLast(_w1, ".ff".length)
214
- })), (((_c) => {
206
+ ff_compiler_Builder.build_(system_, ff_compiler_JsEmitter.EmitBrowser(), mainModuleKeys_, (((_c) => {
215
207
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
216
208
  }))(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, ff_compiler_ModuleCache.new_(0))
217
209
  }
218
210
 
219
- export function check_(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_, checkDependencies_) {
211
+ export function check_(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_) {
220
212
  const packages_ = (((_1) => {
221
- if(_1) {
222
- return ff_compiler_Builder.findPackageFiles_(path_, mustContain_, skipFiles_)
223
- }
224
213
  if(!_1 && ff_core_Path.Path_endsWith(path_, [".firefly", "package.ff"])) {
225
214
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab(ff_core_Path.Path_parent(path_)), ff_core_Option.Some(path_), [])]
226
215
  }
216
+ if(_1) {
217
+ return ff_compiler_Builder.findPackageFilesForDirectory_(path_, mustContain_, skipFiles_)
218
+ }
227
219
  {
228
- return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab(ff_core_Path.Path_parent(path_)), ff_core_Option.None(), [path_])]
220
+ return ff_core_Option.Option_toList(ff_compiler_Builder.findPackageFilesForFile_(path_))
229
221
  }
230
222
  }))(ff_core_Path.Path_isDirectory(path_));
231
223
  const errors_ = ff_core_Array.new_();
232
- for(let for_a = ff_core_List.List_filter(packages_, ((_w1) => {
224
+ const filteredPackages_ = ff_core_List.List_filter(packages_, ((_w1) => {
225
+ return (!ff_core_Path.Path_contains(_w1.root_, [".firefly", "dependencies"]))
226
+ }));
227
+ for(let for_a = ff_core_List.List_filter(filteredPackages_, ((_w1) => {
233
228
  return (!ff_core_List.List_isEmpty(_w1.files_))
234
229
  })), for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
235
230
  const package_ = for_a[for_i];
@@ -262,19 +257,17 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
262
257
  }))(resolvedDependencies_);
263
258
  const newCache_ = ff_compiler_ModuleCache.ModuleCache_without(cache_, newVersion_, path_);
264
259
  const compiler_ = ff_compiler_Compiler.new_(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_, newCache_, lspHook_);
265
- const files_ = (checkDependencies_
266
- ? package_.files_
267
- : ff_core_List.List_filter(package_.files_, ((_w1) => {
268
- return (!ff_core_Path.Path_contains(_w1, [".firefly", "dependencies"]))
269
- })));
270
- for(let for_a = files_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
260
+ for(let for_a = package_.files_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
271
261
  const file_ = for_a[for_i];
272
- const localFile_ = ff_core_Path.Path_base(file_);
262
+ const packagePair_ = resolvedDependencies_.mainPackagePair_;
263
+ const folders_ = ff_core_Path.Path_relativeListTo(ff_core_Option.Option_grab(ff_core_Path.Path_parent(file_)), package_.root_);
264
+ const name_ = ff_core_Option.Option_grab(ff_core_String.String_removeLast(ff_core_Path.Path_base(file_), ".ff"));
265
+ const moduleKey_ = ff_compiler_Syntax.ModuleKey(packagePair_, folders_, name_);
273
266
  ff_core_Try.Try_catch(ff_core_Try.Try_tryCatch(ff_core_Core.try_((() => {
274
267
  if(infer_) {
275
- ff_compiler_Compiler.Compiler_infer(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ".ff".length))
268
+ ff_compiler_Compiler.Compiler_infer(compiler_, moduleKey_)
276
269
  } else {
277
- ff_compiler_Compiler.Compiler_resolve(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ".ff".length))
270
+ ff_compiler_Compiler.Compiler_resolve(compiler_, moduleKey_)
278
271
  }
279
272
  })), ((_1, _2) => {
280
273
  {
@@ -299,8 +292,31 @@ ff_compiler_ModuleCache.ModuleCache_mergeVersions(cache_, compiler_.cache_)
299
292
  return ff_core_Array.Array_drain(errors_)
300
293
  }
301
294
 
302
- export function findPackageFiles_(path_, mustContain_, skipFiles_) {
303
- const files_ = ff_compiler_Builder.findFireflyFiles_(path_, mustContain_, skipFiles_);
295
+ export function findPackageFilesForFile_(file_) {
296
+ if((ff_core_Path.Path_extension(file_) === ".ff")) {
297
+ return ff_core_Option.Some((function() {
298
+ let packageFile_ = ff_core_Option.None();
299
+ let currentDirectory_ = ff_core_Path.Path_parent(file_);
300
+ while(((!ff_core_Option.Option_isEmpty(currentDirectory_)) && ff_core_Option.Option_isEmpty(packageFile_))) {
301
+ packageFile_ = ff_core_Option.Option_filter(ff_core_Option.Option_map(currentDirectory_, ((_w1) => {
302
+ return ff_core_Path.Path_slash(ff_core_Path.Path_slash(_w1, ".firefly"), "package.ff")
303
+ })), ((_w1) => {
304
+ return ff_core_Path.Path_exists(_w1, false, false, false)
305
+ }));
306
+ currentDirectory_ = ff_core_Path.Path_parent(ff_core_Option.Option_grab(currentDirectory_))
307
+ };
308
+ const projectRoot_ = ff_core_Option.Option_else(ff_core_Option.Option_map(packageFile_, ((_w1) => {
309
+ return ff_core_Option.Option_grab(ff_core_Path.Path_parent(ff_core_Option.Option_grab(ff_core_Path.Path_parent(_w1))))
310
+ })), (() => {
311
+ return ff_core_Option.Option_grab(ff_core_Path.Path_parent(file_))
312
+ }));
313
+ return ff_compiler_Builder.PackageFiles(projectRoot_, packageFile_, [file_])
314
+ })())
315
+ } else return ff_core_Option.None()
316
+ }
317
+
318
+ export function findPackageFilesForDirectory_(directory_, mustContain_, skipFiles_) {
319
+ const files_ = ff_compiler_Builder.findFireflyFiles_(directory_, mustContain_, skipFiles_);
304
320
  const split_ = ff_core_List.List_partition(files_, ((_w1) => {
305
321
  return ff_core_Path.Path_endsWith(_w1, [".firefly", "package.ff"])
306
322
  }));
@@ -312,7 +328,8 @@ const files_ = ff_core_List.List_partition(singleFiles_, ((_w1) => {
312
328
  return ff_core_Path.Path_isInsideOf(_w1, projectRoot_)
313
329
  }));
314
330
  singleFiles_ = files_.second_;
315
- return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.Some(packageFile_), files_.first_)
331
+ const packageFiles_ = files_.first_;
332
+ return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.Some(packageFile_), packageFiles_)
316
333
  }));
317
334
  const singleFileProjects_ = ff_core_List.List_map(singleFiles_, ((file_) => {
318
335
  const projectRoot_ = ff_core_Option.Option_grab(ff_core_Path.Path_parent(file_));
@@ -325,21 +342,23 @@ export function findFireflyFiles_(path_, mustContain_, skipFiles_) {
325
342
  const split_ = ff_core_List.List_partition(ff_core_Stream.Stream_toList(ff_core_Path.Path_entries(path_)), ((_w1) => {
326
343
  return ff_core_Path.PathEntry_isDirectory(_w1)
327
344
  }));
328
- const directories_ = ff_core_List.List_filter(ff_core_List.List_map(split_.first_, ((_w1) => {
345
+ const directories_ = split_.first_;
346
+ const files_ = split_.second_;
347
+ const relevantDirectories_ = ff_core_List.List_filter(ff_core_List.List_map(directories_, ((_w1) => {
329
348
  return ff_core_Path.PathEntry_path(_w1)
330
349
  })), ((_w1) => {
331
350
  return ff_core_String.String_all(ff_core_Path.Path_base(_w1), ((c_) => {
332
351
  return (((c_ === 46) || ff_core_Char.Char_isAsciiLower(c_)) || ff_core_Char.Char_isAsciiDigit(c_))
333
352
  }))
334
353
  }));
335
- const fireflyFiles_ = ff_core_List.List_filter(ff_core_List.List_map(split_.second_, ((_w1) => {
354
+ const fireflyFiles_ = ff_core_List.List_filter(ff_core_List.List_map(files_, ((_w1) => {
336
355
  return ff_core_Path.PathEntry_path(_w1)
337
356
  })), ((file_) => {
338
357
  return (((ff_core_Path.Path_extension(file_) === ".ff") && (!ff_core_Set.Set_contains(skipFiles_, ff_core_Path.Path_absolute(file_), ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String))) && ff_core_Option.Option_all(mustContain_, ((s_) => {
339
358
  return ff_core_String.String_contains(ff_core_Path.Path_readText(file_), s_)
340
359
  })))
341
360
  }));
342
- return [...fireflyFiles_, ...ff_core_List.List_flatMap(directories_, ((_w1) => {
361
+ return [...fireflyFiles_, ...ff_core_List.List_flatMap(relevantDirectories_, ((_w1) => {
343
362
  return ff_compiler_Builder.findFireflyFiles_(_w1, mustContain_, skipFiles_)
344
363
  }))]
345
364
  }
@@ -385,7 +404,7 @@ const pkg_ = import$0;
385
404
  pkg_.exec([packageFile_.absolutePath_, "--out-path", outputPath_.absolutePath_, "--target", ff_core_List.List_join(targets_, ",")])
386
405
  }
387
406
 
388
- export async function build_$(system_, emitTarget_, mainPackage_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
407
+ export async function build_$(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
389
408
  if((await ff_core_Path.Path_exists$(tempPath_, false, false, false, $task))) {
390
409
  (await ff_core_Path.Path_delete$(tempPath_, 0, 100, $task))
391
410
  };
@@ -395,8 +414,8 @@ const jsPathFile_ = (await ff_core_Path.Path_slash$(tempPath_, "js", $task));
395
414
  const success_ = (await ff_core_Core.do_$((async ($task) => {
396
415
  const compiler_ = (await ff_compiler_Compiler.new_$(emitTarget_, (await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), compilerModulePath_, jsPathFile_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_(), $task));
397
416
  for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
398
- const mainModule_ = for_a[for_i];
399
- (await ff_compiler_Compiler.Compiler_emit$(compiler_, mainPackage_, mainModule_, true, $task))
417
+ const moduleKey_ = for_a[for_i];
418
+ (await ff_compiler_Compiler.Compiler_emit$(compiler_, moduleKey_, true, $task))
400
419
  };
401
420
  if(printMeasurements_) {
402
421
  (await ff_compiler_Compiler.Compiler_printMeasurements$(compiler_, $task))
@@ -450,46 +469,41 @@ if((result_.exitCode_ !== 0)) {
450
469
  }
451
470
 
452
471
  export async function buildViaBuildSystem_$(system_, fireflyPath_, mainFiles_, target_, $task) {
453
- const mainPaths_ = (await ff_core_List.List_map$(mainFiles_, (async (_w1, $task) => {
454
- return (await ff_core_Path.Path_absolute$(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$((await ff_core_NodeSystem.NodeSystem_path$(system_, _w1, $task)), $task))), $task))
455
- }), $task));
456
- {
457
- const if_o = ff_core_List.List_find(mainPaths_, ((_w1) => {
458
- return (_w1 !== ff_core_List.List_grabFirst(mainPaths_))
459
- }))
460
- if(if_o.Some) {
461
- const path_ = if_o.value_;
462
- ff_core_Core.panic_(((("Can't build multiple main files in different directories: " + path_) + " vs. ") + ff_core_List.List_grabFirst(mainPaths_)))
463
- }
464
- };
465
- const resolvedDependencies_ = (await ff_compiler_Dependencies.process_$((await ff_core_NodeSystem.NodeSystem_httpClient$(system_, $task)), (await ff_compiler_DependencyLock.new_$((await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), $task)), (await ff_core_NodeSystem.NodeSystem_path$(system_, ff_core_List.List_grabFirst(mainFiles_), $task)), $task));
472
+ const resolvedDependencies_ = (await ff_compiler_Dependencies.process_$((await ff_core_NodeSystem.NodeSystem_httpClient$(system_, $task)), (await ff_compiler_DependencyLock.new_$((await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), $task)), ff_core_List.List_grabFirst(mainFiles_), $task));
466
473
  const fixedPackagePaths_ = (ff_core_Map.Map_contains(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
467
474
  ? resolvedDependencies_.packagePaths_
468
475
  : ff_core_Map.Map_add(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), (await ff_core_Path.Path_slash$(fireflyPath_, "core", $task)), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair));
476
+ const packageRoot_ = ff_core_Map.Map_grab(resolvedDependencies_.packagePaths_, resolvedDependencies_.mainPackagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair);
477
+ const mainModuleKeys_ = (await ff_core_List.List_map$(mainFiles_, (async (mainFile_, $task) => {
478
+ return (await ff_core_Option.Option_else$((await ff_compiler_Syntax.PackagePair_moduleKey$(resolvedDependencies_.mainPackagePair_, packageRoot_, mainFile_, $task)), (async ($task) => {
479
+ return ff_core_Core.panic_(((("Can't build multiple main files in different packages: " + (await ff_core_Path.Path_absolute$(mainFile_, $task))) + " isn't part of ") + (await ff_core_Path.Path_absolute$(packageRoot_, $task))))
480
+ }), $task))
481
+ }), $task));
469
482
  if((target_ !== "browser")) {
470
483
  ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target only - the restriction can be lifted")
471
484
  };
472
- (await ff_compiler_Builder.build_$(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_List.List_map(mainFiles_, ((_w1) => {
473
- return ff_core_String.String_dropLast(_w1, ".ff".length)
474
- })), (((_c) => {
485
+ (await ff_compiler_Builder.build_$(system_, ff_compiler_JsEmitter.EmitBrowser(), mainModuleKeys_, (((_c) => {
475
486
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
476
487
  }))(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, ff_compiler_ModuleCache.new_(0), $task))
477
488
  }
478
489
 
479
- export async function check_$(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_, checkDependencies_, $task) {
490
+ export async function check_$(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_, $task) {
480
491
  const packages_ = (await ((async (_1, $task) => {
481
- if(_1) {
482
- return (await ff_compiler_Builder.findPackageFiles_$(path_, mustContain_, skipFiles_, $task))
483
- }
484
492
  if(!_1 && (await ff_core_Path.Path_endsWith$(path_, [".firefly", "package.ff"], $task))) {
485
493
  return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(path_, $task))), ff_core_Option.Some(path_), [])]
486
494
  }
495
+ if(_1) {
496
+ return (await ff_compiler_Builder.findPackageFilesForDirectory_$(path_, mustContain_, skipFiles_, $task))
497
+ }
487
498
  {
488
- return [ff_compiler_Builder.PackageFiles(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(path_, $task))), ff_core_Option.None(), [path_])]
499
+ return ff_core_Option.Option_toList((await ff_compiler_Builder.findPackageFilesForFile_$(path_, $task)))
489
500
  }
490
501
  }))((await ff_core_Path.Path_isDirectory$(path_, $task)), $task));
491
502
  const errors_ = ff_core_Array.new_();
492
- for(let for_a = ff_core_List.List_filter(packages_, ((_w1) => {
503
+ const filteredPackages_ = (await ff_core_List.List_filter$(packages_, (async (_w1, $task) => {
504
+ return (!(await ff_core_Path.Path_contains$(_w1.root_, [".firefly", "dependencies"], $task)))
505
+ }), $task));
506
+ for(let for_a = ff_core_List.List_filter(filteredPackages_, ((_w1) => {
493
507
  return (!ff_core_List.List_isEmpty(_w1.files_))
494
508
  })), for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
495
509
  const package_ = for_a[for_i];
@@ -522,19 +536,17 @@ return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.pac
522
536
  }))(resolvedDependencies_);
523
537
  const newCache_ = (await ff_compiler_ModuleCache.ModuleCache_without$(cache_, newVersion_, path_, $task));
524
538
  const compiler_ = (await ff_compiler_Compiler.new_$(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_, newCache_, lspHook_, $task));
525
- const files_ = (checkDependencies_
526
- ? package_.files_
527
- : (await ff_core_List.List_filter$(package_.files_, (async (_w1, $task) => {
528
- return (!(await ff_core_Path.Path_contains$(_w1, [".firefly", "dependencies"], $task)))
529
- }), $task)));
530
- for(let for_a = files_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
539
+ for(let for_a = package_.files_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
531
540
  const file_ = for_a[for_i];
532
- const localFile_ = (await ff_core_Path.Path_base$(file_, $task));
541
+ const packagePair_ = resolvedDependencies_.mainPackagePair_;
542
+ const folders_ = (await ff_core_Path.Path_relativeListTo$(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(file_, $task))), package_.root_, $task));
543
+ const name_ = ff_core_Option.Option_grab(ff_core_String.String_removeLast((await ff_core_Path.Path_base$(file_, $task)), ".ff"));
544
+ const moduleKey_ = ff_compiler_Syntax.ModuleKey(packagePair_, folders_, name_);
533
545
  ff_core_Try.Try_catch(ff_core_Try.Try_tryCatch((await ff_core_Core.try_$((async ($task) => {
534
546
  if(infer_) {
535
- (await ff_compiler_Compiler.Compiler_infer$(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ".ff".length), $task))
547
+ (await ff_compiler_Compiler.Compiler_infer$(compiler_, moduleKey_, $task))
536
548
  } else {
537
- (await ff_compiler_Compiler.Compiler_resolve$(compiler_, resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(localFile_, ".ff".length), $task))
549
+ (await ff_compiler_Compiler.Compiler_resolve$(compiler_, moduleKey_, $task))
538
550
  }
539
551
  }), $task)), ((_1, _2) => {
540
552
  {
@@ -559,8 +571,31 @@ ff_compiler_ModuleCache.ModuleCache_mergeVersions(cache_, compiler_.cache_)
559
571
  return ff_core_Array.Array_drain(errors_)
560
572
  }
561
573
 
562
- export async function findPackageFiles_$(path_, mustContain_, skipFiles_, $task) {
563
- const files_ = (await ff_compiler_Builder.findFireflyFiles_$(path_, mustContain_, skipFiles_, $task));
574
+ export async function findPackageFilesForFile_$(file_, $task) {
575
+ if(((await ff_core_Path.Path_extension$(file_, $task)) === ".ff")) {
576
+ return ff_core_Option.Some((await (async function() {
577
+ let packageFile_ = ff_core_Option.None();
578
+ let currentDirectory_ = (await ff_core_Path.Path_parent$(file_, $task));
579
+ while(((!ff_core_Option.Option_isEmpty(currentDirectory_)) && ff_core_Option.Option_isEmpty(packageFile_))) {
580
+ packageFile_ = (await ff_core_Option.Option_filter$((await ff_core_Option.Option_map$(currentDirectory_, (async (_w1, $task) => {
581
+ return (await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$(_w1, ".firefly", $task)), "package.ff", $task))
582
+ }), $task)), (async (_w1, $task) => {
583
+ return (await ff_core_Path.Path_exists$(_w1, false, false, false, $task))
584
+ }), $task));
585
+ currentDirectory_ = (await ff_core_Path.Path_parent$(ff_core_Option.Option_grab(currentDirectory_), $task))
586
+ };
587
+ const projectRoot_ = (await ff_core_Option.Option_else$((await ff_core_Option.Option_map$(packageFile_, (async (_w1, $task) => {
588
+ return ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(_w1, $task))), $task)))
589
+ }), $task)), (async ($task) => {
590
+ return ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(file_, $task)))
591
+ }), $task));
592
+ return ff_compiler_Builder.PackageFiles(projectRoot_, packageFile_, [file_])
593
+ })()))
594
+ } else return ff_core_Option.None()
595
+ }
596
+
597
+ export async function findPackageFilesForDirectory_$(directory_, mustContain_, skipFiles_, $task) {
598
+ const files_ = (await ff_compiler_Builder.findFireflyFiles_$(directory_, mustContain_, skipFiles_, $task));
564
599
  const split_ = (await ff_core_List.List_partition$(files_, (async (_w1, $task) => {
565
600
  return (await ff_core_Path.Path_endsWith$(_w1, [".firefly", "package.ff"], $task))
566
601
  }), $task));
@@ -572,7 +607,8 @@ const files_ = (await ff_core_List.List_partition$(singleFiles_, (async (_w1, $t
572
607
  return (await ff_core_Path.Path_isInsideOf$(_w1, projectRoot_, $task))
573
608
  }), $task));
574
609
  singleFiles_ = files_.second_;
575
- return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.Some(packageFile_), files_.first_)
610
+ const packageFiles_ = files_.first_;
611
+ return ff_compiler_Builder.PackageFiles(projectRoot_, ff_core_Option.Some(packageFile_), packageFiles_)
576
612
  }), $task));
577
613
  const singleFileProjects_ = (await ff_core_List.List_map$(singleFiles_, (async (file_, $task) => {
578
614
  const projectRoot_ = ff_core_Option.Option_grab((await ff_core_Path.Path_parent$(file_, $task)));
@@ -585,21 +621,23 @@ export async function findFireflyFiles_$(path_, mustContain_, skipFiles_, $task)
585
621
  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) => {
586
622
  return (await ff_core_Path.PathEntry_isDirectory$(_w1, $task))
587
623
  }), $task));
588
- const directories_ = (await ff_core_List.List_filter$((await ff_core_List.List_map$(split_.first_, (async (_w1, $task) => {
624
+ const directories_ = split_.first_;
625
+ const files_ = split_.second_;
626
+ const relevantDirectories_ = (await ff_core_List.List_filter$((await ff_core_List.List_map$(directories_, (async (_w1, $task) => {
589
627
  return (await ff_core_Path.PathEntry_path$(_w1, $task))
590
628
  }), $task)), (async (_w1, $task) => {
591
629
  return ff_core_String.String_all((await ff_core_Path.Path_base$(_w1, $task)), ((c_) => {
592
630
  return (((c_ === 46) || ff_core_Char.Char_isAsciiLower(c_)) || ff_core_Char.Char_isAsciiDigit(c_))
593
631
  }))
594
632
  }), $task));
595
- const fireflyFiles_ = (await ff_core_List.List_filter$((await ff_core_List.List_map$(split_.second_, (async (_w1, $task) => {
633
+ const fireflyFiles_ = (await ff_core_List.List_filter$((await ff_core_List.List_map$(files_, (async (_w1, $task) => {
596
634
  return (await ff_core_Path.PathEntry_path$(_w1, $task))
597
635
  }), $task)), (async (file_, $task) => {
598
636
  return ((((await ff_core_Path.Path_extension$(file_, $task)) === ".ff") && (!ff_core_Set.Set_contains(skipFiles_, (await ff_core_Path.Path_absolute$(file_, $task)), ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String))) && (await ff_core_Option.Option_all$(mustContain_, (async (s_, $task) => {
599
637
  return ff_core_String.String_contains((await ff_core_Path.Path_readText$(file_, $task)), s_)
600
638
  }), $task)))
601
639
  }), $task));
602
- return [...fireflyFiles_, ...(await ff_core_List.List_flatMap$(directories_, (async (_w1, $task) => {
640
+ return [...fireflyFiles_, ...(await ff_core_List.List_flatMap$(relevantDirectories_, (async (_w1, $task) => {
603
641
  return (await ff_compiler_Builder.findFireflyFiles_$(_w1, mustContain_, skipFiles_, $task))
604
642
  }), $task))]
605
643
  }