firefly-compiler 0.4.21 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/Dictionaries.ff +10 -10
- package/compiler/Inference.ff +167 -148
- package/compiler/JsEmitter.ff +2 -2
- package/compiler/LspHook.ff +2 -1
- package/compiler/Main.ff +12 -4
- package/compiler/Patterns.ff +1 -1
- package/compiler/Resolver.ff +154 -146
- package/compiler/Substitution.ff +2 -2
- package/compiler/Unification.ff +1 -1
- package/core/Map.ff +8 -0
- package/core/Set.ff +7 -0
- package/lsp/Handler.ff +11 -3
- package/output/js/ff/compiler/Dictionaries.mjs +18 -18
- package/output/js/ff/compiler/Inference.mjs +96 -72
- package/output/js/ff/compiler/JsEmitter.mjs +8 -6
- package/output/js/ff/compiler/Main.mjs +16 -5
- package/output/js/ff/compiler/Patterns.mjs +4 -4
- package/output/js/ff/compiler/Resolver.mjs +412 -224
- package/output/js/ff/compiler/Substitution.mjs +4 -4
- package/output/js/ff/compiler/Unification.mjs +4 -4
- package/output/js/ff/core/Map.mjs +26 -0
- package/output/js/ff/core/Set.mjs +16 -0
- package/package.json +1 -1
- package/vscode/package.json +1 -1
- package/bin/firefly.mjs +0 -2
- package/guide/Main.ff +0 -22
package/compiler/Resolver.ff
CHANGED
|
@@ -20,6 +20,12 @@ class ResolverState(
|
|
|
20
20
|
mutable nextUnificationVariableIndex: Int
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
+
data CaseVariable(
|
|
24
|
+
at: Location
|
|
25
|
+
name: String
|
|
26
|
+
asBound: Option[String]
|
|
27
|
+
)
|
|
28
|
+
|
|
23
29
|
make(packagePair: PackagePair, moduleName: String, lspHook: LspHook): Resolver {
|
|
24
30
|
Resolver(
|
|
25
31
|
variables = [].toMap()
|
|
@@ -77,8 +83,8 @@ extend self: Resolver {
|
|
|
77
83
|
|
|
78
84
|
processImports(imports: List[DImport], modules: List[Module]): Resolver {
|
|
79
85
|
mutable resolver = self
|
|
80
|
-
imports.each {
|
|
81
|
-
modules.find {
|
|
86
|
+
imports.each {import =>
|
|
87
|
+
modules.find {_.file.dropLast(3) == import.file}.{
|
|
82
88
|
| Some(module) =>
|
|
83
89
|
resolver = resolver.processDefinitions(module, Some(import.alias))
|
|
84
90
|
| None =>
|
|
@@ -95,7 +101,7 @@ extend self: Resolver {
|
|
|
95
101
|
module.file.dropLast(3) + "." + name
|
|
96
102
|
importAlias.{
|
|
97
103
|
| None => [Pair(name, full), Pair(full, full)]
|
|
98
|
-
| Some(alias) {
|
|
104
|
+
| Some(alias) {unqualified} => [Pair(alias + "." + name, full), Pair(name, full), Pair(full, full)]
|
|
99
105
|
| Some(alias) => [Pair(alias + "." + name, full), Pair(full, full)]
|
|
100
106
|
}
|
|
101
107
|
}
|
|
@@ -103,20 +109,20 @@ extend self: Resolver {
|
|
|
103
109
|
module.packagePair.group == "ff" &&
|
|
104
110
|
module.packagePair.name == "core" &&
|
|
105
111
|
module.file == "Core.ff"
|
|
106
|
-
let lets = module.lets.flatMap {
|
|
107
|
-
let letLocations = module.lets.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}
|
|
108
|
-
let functions = module.functions.flatMap {
|
|
112
|
+
let lets = module.lets.flatMap {entry(_.name, isCore)}.toMap()
|
|
113
|
+
let letLocations = module.lets.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()
|
|
114
|
+
let functions = module.functions.flatMap {entry(_.signature.name, isCore)}.toMap()
|
|
109
115
|
let functionLocations = module.functions.flatMap {d => entry(d.signature.name, True).map {_.mapSecond {_ => d.at}} }.toMap()
|
|
110
|
-
let traitMethods = module.traits.flatMap {
|
|
111
|
-
let traitMethodLocations = module.traits.flatMap {_.methods}.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}
|
|
112
|
-
let traits = module.traits.flatMap {
|
|
113
|
-
let traitLocations = module.traits.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}
|
|
114
|
-
let types = module.types.flatMap {
|
|
116
|
+
let traitMethods = module.traits.flatMap {_.methods }.flatMap {entry(_.name, False)}.toMap()
|
|
117
|
+
let traitMethodLocations = module.traits.flatMap {_.methods}.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()
|
|
118
|
+
let traits = module.traits.flatMap {entry(_.name, True) }.toMap()
|
|
119
|
+
let traitLocations = module.traits.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()
|
|
120
|
+
let types = module.types.flatMap {entry(_.name, True) }.toMap()
|
|
115
121
|
let typeGenerics = module.types.flatMap {d => entry(d.name, True).map {p => Pair(p.first, d.generics)}}.toMap()
|
|
116
|
-
let typeLocations = module.types.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}
|
|
117
|
-
let asyncTypes = module.types.filter {
|
|
118
|
-
.flatMap {
|
|
119
|
-
let variants = module.types.flatMap {
|
|
122
|
+
let typeLocations = module.types.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()
|
|
123
|
+
let asyncTypes = module.types.filter {_.generics.first().any {_ == "Q$"}}
|
|
124
|
+
.flatMap {entry(_.name, True).map {_.first}}.toSet()
|
|
125
|
+
let variants = module.types.flatMap {_.variants }.flatMap {entry(_.name, True)}.toMap()
|
|
120
126
|
self.Resolver(
|
|
121
127
|
variables = self.variables.addAll(lets).addAll(functions).addAll(traitMethods)
|
|
122
128
|
variableLocations = self.variableLocations.addAll(letLocations).addAll(functionLocations).addAll(traitMethodLocations)
|
|
@@ -276,132 +282,134 @@ extend self: Resolver {
|
|
|
276
282
|
)
|
|
277
283
|
}
|
|
278
284
|
|
|
279
|
-
resolveTerm(term: Term, topLevel: Bool): Term {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
self.lspHook.
|
|
289
|
-
|
|
290
|
-
|
|
285
|
+
resolveTerm(term: Term, topLevel: Bool, inField: Bool = False): Term {
|
|
286
|
+
term.{
|
|
287
|
+
| EString _ => term
|
|
288
|
+
| EChar _ => term
|
|
289
|
+
| EInt _ => term
|
|
290
|
+
| EFloat _ => term
|
|
291
|
+
| EVariable e =>
|
|
292
|
+
if(self.lspHook.isEnabled()) {
|
|
293
|
+
let at = self.variableLocations.get(e.name).else {e.at}
|
|
294
|
+
if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(at)) {
|
|
295
|
+
self.lspHook.emit(
|
|
296
|
+
ResolveSymbolHook(
|
|
297
|
+
SymbolHook(e.name, e.at, at), None, topLevel = True
|
|
298
|
+
)
|
|
291
299
|
)
|
|
292
|
-
|
|
300
|
+
}
|
|
293
301
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
302
|
+
self.variables.get(e.name).map {e.EVariable(name = _)}.else {term}
|
|
303
|
+
| EList(at, t, items) =>
|
|
304
|
+
EList(at, self.resolveType(t, topLevel), items.map {| Pair(item, spread) =>
|
|
305
|
+
Pair(self.resolveTerm(item, topLevel), spread)
|
|
306
|
+
})
|
|
307
|
+
| EVariant(at, name, typeArguments, arguments) =>
|
|
308
|
+
EVariant(
|
|
309
|
+
at = at
|
|
310
|
+
name = self.variants.get(name).else {name}
|
|
311
|
+
typeArguments = typeArguments.map {self.resolveType(_, topLevel)}
|
|
312
|
+
arguments = arguments.map {_.map {a => a.Argument(value = self.resolveTerm(a.value, topLevel))}}
|
|
313
|
+
)
|
|
314
|
+
| EVariantIs(at, name, typeArguments) =>
|
|
315
|
+
EVariantIs(
|
|
316
|
+
at = at
|
|
317
|
+
name = self.variants.get(name).else {throw(CompileError(at, "No such variant: " + name))}
|
|
318
|
+
typeArguments = typeArguments.map {self.resolveType(_, topLevel)}
|
|
319
|
+
)
|
|
320
|
+
| ECopy(at, name, record, arguments) =>
|
|
321
|
+
ECopy(
|
|
322
|
+
at = at
|
|
323
|
+
name = self.variants.get(name).else {name}
|
|
324
|
+
record = self.resolveTerm(record, topLevel, inField = True)
|
|
325
|
+
arguments = arguments.map {f => f.Field(value = self.resolveTerm(f.value, topLevel))}
|
|
326
|
+
)
|
|
327
|
+
| EField e =>
|
|
328
|
+
e.EField(record = self.resolveTerm(e.record, topLevel, inField = True))
|
|
329
|
+
| ELambda(at, Lambda(lambdaAt, _, cases)) =>
|
|
330
|
+
let effect = self.makeEffectArgument(lambdaAt, topLevel)
|
|
331
|
+
ELambda(at, Lambda(lambdaAt, effect, cases.map {self.resolveCase(_, topLevel)}))
|
|
332
|
+
| EPipe(at, value, effect, function) =>
|
|
333
|
+
EPipe(
|
|
334
|
+
at = at
|
|
335
|
+
value = self.resolveTerm(value, topLevel)
|
|
336
|
+
effect = self.resolveType(effect, topLevel)
|
|
337
|
+
function = self.resolveTerm(function, topLevel)
|
|
338
|
+
)
|
|
339
|
+
| ECall(at, DynamicCall target, effect, typeArguments, arguments, dictionaries) =>
|
|
340
|
+
ECall(
|
|
341
|
+
at = at
|
|
342
|
+
target = target.DynamicCall(function = self.resolveTerm(target.function, topLevel))
|
|
343
|
+
effect = self.resolveType(effect, topLevel)
|
|
344
|
+
typeArguments = typeArguments.map {self.resolveType(_, topLevel)}
|
|
345
|
+
arguments = arguments.map {a => a.Argument(value = self.resolveTerm(a.value, topLevel))}
|
|
346
|
+
dictionaries = dictionaries
|
|
347
|
+
)
|
|
348
|
+
| ECall(at, StaticCall _, _, _, _, _) =>
|
|
349
|
+
throw(CompileError(at, "Internal error: Static calls not expected in the Resolver phase"))
|
|
350
|
+
| ERecord(at, fields) =>
|
|
351
|
+
ERecord(
|
|
352
|
+
at = at
|
|
353
|
+
fields = fields.map {f => f.Field(value = self.resolveTerm(f.value, topLevel))}
|
|
354
|
+
)
|
|
355
|
+
| EWildcard e =>
|
|
356
|
+
if(e.index == 0) {throw(CompileError(e.at, "Unbound wildcard"))}
|
|
357
|
+
e.EWildcard()
|
|
358
|
+
| EFunctions(at, functions, body) =>
|
|
359
|
+
let functionMap = functions.map {_.signature.name}.map {name => Pair(name, name)}.toMap()
|
|
360
|
+
let locationMap = functions.map {_.signature}.map {s => Pair(s.name, s.at)}.toMap()
|
|
361
|
+
let self2 = self.Resolver(
|
|
362
|
+
variables = self.variables.addAll(functionMap)
|
|
363
|
+
variableLocations = self.variableLocations.addAll(locationMap)
|
|
364
|
+
)
|
|
365
|
+
EFunctions(
|
|
366
|
+
at = at
|
|
367
|
+
functions = functions.map {self2.resolveFunctionDefinition(_, topLevel, False)}
|
|
368
|
+
body = self2.resolveTerm(body, topLevel)
|
|
369
|
+
)
|
|
370
|
+
| ELet e =>
|
|
371
|
+
let self2 = self.Resolver(
|
|
372
|
+
variables = self.variables.add(e.name, e.name)
|
|
373
|
+
variableLocations = self.variableLocations.add(e.name, e.at)
|
|
374
|
+
)
|
|
375
|
+
if(self.lspHook.isEnabled()) {
|
|
376
|
+
if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(e.at)) {
|
|
377
|
+
self.lspHook.emit(
|
|
378
|
+
ResolveSymbolHook(
|
|
379
|
+
SymbolHook(e.name, e.at, e.at), None, topLevel = False
|
|
380
|
+
)
|
|
373
381
|
)
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
e.ELet(
|
|
378
|
-
valueType = self.resolveType(e.valueType, topLevel)
|
|
379
|
-
value = self.resolveTerm(e.value, topLevel)
|
|
380
|
-
body = self2.resolveTerm(e.body, topLevel)
|
|
381
|
-
)
|
|
382
|
-
| ESequential(at, before, after), _ =>
|
|
383
|
-
ESequential(
|
|
384
|
-
at = at
|
|
385
|
-
before = self.resolveTerm(before, topLevel)
|
|
386
|
-
after = self.resolveTerm(after, topLevel)
|
|
387
|
-
)
|
|
388
|
-
| EAssign(at, operator, variable, value), _ =>
|
|
389
|
-
EAssign(
|
|
390
|
-
at = at
|
|
391
|
-
operator = operator
|
|
392
|
-
variable = self.variables.get(variable).else {
|
|
393
|
-
throw(CompileError(at, "No such variable: " + variable))
|
|
382
|
+
}
|
|
394
383
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
384
|
+
e.ELet(
|
|
385
|
+
valueType = self.resolveType(e.valueType, topLevel)
|
|
386
|
+
value = self.resolveTerm(e.value, topLevel)
|
|
387
|
+
body = self2.resolveTerm(e.body, topLevel)
|
|
388
|
+
)
|
|
389
|
+
| ESequential(at, before, after) =>
|
|
390
|
+
ESequential(
|
|
391
|
+
at = at
|
|
392
|
+
before = self.resolveTerm(before, topLevel)
|
|
393
|
+
after = self.resolveTerm(after, topLevel)
|
|
394
|
+
)
|
|
395
|
+
| EAssign(at, operator, variable, value) =>
|
|
396
|
+
EAssign(
|
|
397
|
+
at = at
|
|
398
|
+
operator = operator
|
|
399
|
+
variable = self.variables.get(variable).else {
|
|
400
|
+
throw(CompileError(at, "No such variable: " + variable))
|
|
401
|
+
}
|
|
402
|
+
value = self.resolveTerm(value, topLevel)
|
|
403
|
+
)
|
|
404
|
+
| EAssignField(at, operator, record, field, value) =>
|
|
405
|
+
EAssignField(
|
|
406
|
+
at = at
|
|
407
|
+
operator = operator
|
|
408
|
+
record = self.resolveTerm(record, topLevel)
|
|
409
|
+
field = field
|
|
410
|
+
value = self.resolveTerm(value, topLevel)
|
|
411
|
+
)
|
|
412
|
+
}
|
|
405
413
|
}
|
|
406
414
|
|
|
407
415
|
resolveType(type: Type, topLevel: Bool): Type {
|
|
@@ -535,7 +543,7 @@ extend self: Resolver {
|
|
|
535
543
|
}
|
|
536
544
|
|
|
537
545
|
resolveCase(case: MatchCase, topLevel: Bool): MatchCase {
|
|
538
|
-
function findVariables(pattern: MatchPattern): Map[String,
|
|
546
|
+
function findVariables(pattern: MatchPattern): Map[String, CaseVariable] {
|
|
539
547
|
| PString _ =>
|
|
540
548
|
Map.empty()
|
|
541
549
|
| PInt _ =>
|
|
@@ -543,22 +551,22 @@ extend self: Resolver {
|
|
|
543
551
|
| PChar _ =>
|
|
544
552
|
Map.empty()
|
|
545
553
|
| PVariable(at, Some(name)) =>
|
|
546
|
-
[Pair(name,
|
|
554
|
+
[Pair(name, CaseVariable(at, name, None))].toMap()
|
|
547
555
|
| PVariable(_, None) =>
|
|
548
556
|
Map.empty()
|
|
549
557
|
| PVariant(_, _, patterns) =>
|
|
550
558
|
patterns.map(findVariables).foldLeft(Map.empty()) {_.addAll(_)}
|
|
551
|
-
| PVariantAs(at,
|
|
552
|
-
variable.toList().map {x => Pair(x,
|
|
559
|
+
| PVariantAs(at, variant, variableAt, variable) =>
|
|
560
|
+
variable.toList().map {x => Pair(x, CaseVariable(variableAt, x, Some(variant)))}.toMap()
|
|
553
561
|
| PAlias(at, pattern, variable) =>
|
|
554
|
-
[Pair(variable,
|
|
562
|
+
[Pair(variable, CaseVariable(at, variable, None))].toMap().addAll(findVariables(pattern))
|
|
555
563
|
}
|
|
556
564
|
let variableMap = case.patterns.map(findVariables).foldLeft(Map.empty()) {_.addAll(_)}
|
|
557
565
|
mutable guards = []
|
|
558
566
|
let variableMap2 = case.guards.foldLeft(variableMap) {variableMap1, g =>
|
|
559
567
|
let self2 = self.Resolver(
|
|
560
|
-
variables = self.variables.addAll(variableMap1.mapValues {_, p => p.
|
|
561
|
-
variableLocations = self.variableLocations.addAll(variableMap1.mapValues {_, p => p.
|
|
568
|
+
variables = self.variables.addAll(variableMap1.mapValues {_, p => p.name})
|
|
569
|
+
variableLocations = self.variableLocations.addAll(variableMap1.mapValues {_, p => p.at})
|
|
562
570
|
)
|
|
563
571
|
let guard = g.MatchGuard(
|
|
564
572
|
term = self2.resolveTerm(g.term, topLevel)
|
|
@@ -568,8 +576,8 @@ extend self: Resolver {
|
|
|
568
576
|
variableMap1.addAll(findVariables(guard.pattern))
|
|
569
577
|
}
|
|
570
578
|
let self3 = self.Resolver(
|
|
571
|
-
variables = self.variables.addAll(variableMap2.mapValues {_, p => p.
|
|
572
|
-
variableLocations = self.variableLocations.addAll(variableMap2.mapValues {_, p => p.
|
|
579
|
+
variables = self.variables.addAll(variableMap2.mapValues {_, p => p.name})
|
|
580
|
+
variableLocations = self.variableLocations.addAll(variableMap2.mapValues {_, p => p.at})
|
|
573
581
|
)
|
|
574
582
|
MatchCase(
|
|
575
583
|
at = case.at
|
package/compiler/Substitution.ff
CHANGED
|
@@ -154,9 +154,9 @@ extend self: Substitution {
|
|
|
154
154
|
|
|
155
155
|
substituteType(type: Type): Type {
|
|
156
156
|
| TVariable(at, i) =>
|
|
157
|
-
if(self.has(i)) {
|
|
157
|
+
if(self.has(i)) {self.substituteType(self.get(i))} else {TConstructor(at, core("Nothing"), [])}
|
|
158
158
|
| TConstructor t =>
|
|
159
|
-
t.TConstructor(generics = t.generics.map {
|
|
159
|
+
t.TConstructor(generics = t.generics.map {g => self.substituteType(g)})
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
get(index: Int): Type {
|
package/compiler/Unification.ff
CHANGED
|
@@ -152,7 +152,7 @@ extend self: Unification {
|
|
|
152
152
|
substitute(type: Type): Type {
|
|
153
153
|
| TVariable(_, i) {self.get(i) | Some(t)} => self.substitute(t)
|
|
154
154
|
| TVariable(_, _) => type
|
|
155
|
-
| TConstructor t => t.TConstructor(generics = t.generics.map {
|
|
155
|
+
| TConstructor t => t.TConstructor(generics = t.generics.map {g => self.substitute(g)})
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
unify(at: Location, t1: Type, t2: Type): Unit {
|
package/core/Map.ff
CHANGED
|
@@ -18,6 +18,14 @@ extend self[K: Order, V]: Map[K, V] {
|
|
|
18
18
|
Map(result)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
addList(that: List[Pair[K, V]]): Map[K, V] {
|
|
22
|
+
mutable result = self.redBlack
|
|
23
|
+
that.each {| Pair(k, v) =>
|
|
24
|
+
result = RbMap.insert(k, v, result)
|
|
25
|
+
}
|
|
26
|
+
Map(result)
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
get(key: K): Option[V] {
|
|
22
30
|
self.redBlack.get(key)
|
|
23
31
|
}
|
package/core/Set.ff
CHANGED
|
@@ -7,6 +7,13 @@ empty[T](): Set[T] {
|
|
|
7
7
|
extend self[T: Order]: Set[T] {
|
|
8
8
|
add(value: T): Set[T] {Set(self.map.add(value, Unit))}
|
|
9
9
|
addAll(that: Set[T]): Set[T] {Set(self.map.addAll(that.map))}
|
|
10
|
+
addList(that: List[T]): Set[T] {
|
|
11
|
+
mutable result = self.map
|
|
12
|
+
that.each {k =>
|
|
13
|
+
result = result.add(k, Unit)
|
|
14
|
+
}
|
|
15
|
+
Set(result)
|
|
16
|
+
}
|
|
10
17
|
remove(value: T): Set[T] {Set(self.map.remove(value))}
|
|
11
18
|
removeAll(that: Set[T]): Set[T] {Set(self.map.removeAll(that.map))}
|
|
12
19
|
contains(value: T): Bool {self.map.contains(value)}
|
package/lsp/Handler.ff
CHANGED
|
@@ -436,7 +436,13 @@ extend self: Handler {
|
|
|
436
436
|
| InferPatternHook h {h.pattern | PVariantAs p} => Some(Definition(p.variableAt, p.name, False))
|
|
437
437
|
| InferPatternHook h {h.pattern | PVariable p} => p.name.map {Definition(p.at, _, False)}
|
|
438
438
|
| InferPatternHook h {h.pattern | PAlias p} => Some(Definition(p.at, p.variable, False))
|
|
439
|
-
| _ =>
|
|
439
|
+
| InferRecordFieldHook h {h.unification.substitute(h.recordType) | TConstructor(_, n, ts)} =>
|
|
440
|
+
let fieldNames = n.split('$').dropFirst(1)
|
|
441
|
+
let fieldDefinedAt = fieldNames.zip(ts).collectFirst {| Pair(name, t) =>
|
|
442
|
+
if(name == h.fieldName) {t.at}
|
|
443
|
+
}
|
|
444
|
+
fieldDefinedAt.map {Definition(_, h.fieldName, False)}
|
|
445
|
+
| h => None
|
|
440
446
|
}.filter {pair => !pair.at.file.endsWith(">")}
|
|
441
447
|
|
|
442
448
|
function unqualify(qualifiedName: String): String {
|
|
@@ -445,7 +451,6 @@ extend self: Handler {
|
|
|
445
451
|
|
|
446
452
|
definedAtList.first().{
|
|
447
453
|
| Some(definition) =>
|
|
448
|
-
//Log.trace("handleReferences definedAt: " + Show.show(definedAt))
|
|
449
454
|
let lspHook = LspHook.make(at = None, definedAt = Some(definition.at), insertIdentifier = False, trackSymbols = False)
|
|
450
455
|
let localCheck = local || definition.local
|
|
451
456
|
let path = if(localCheck) {system.path(targetAt.file)} else {self.rootPath.grab()}
|
|
@@ -456,7 +461,7 @@ extend self: Handler {
|
|
|
456
461
|
let errors = Builder.check(system, self.fireflyPath, path, mustContain, self.virtualFiles, lspHook, True)
|
|
457
462
|
errors.each {| CompileError(at, message) =>
|
|
458
463
|
Log.trace("findReferences second check error: " + message + " in " + at.file + ":" + at.line + ":" + at.column)
|
|
459
|
-
}
|
|
464
|
+
}
|
|
460
465
|
|
|
461
466
|
let referencesResult = lspHook.results().collect {
|
|
462
467
|
| ResolveSymbolHook h => Some(h.symbol.usageAt)
|
|
@@ -468,11 +473,14 @@ extend self: Handler {
|
|
|
468
473
|
| InferArgumentHook h {h.arguments.dropFirst(h.argumentIndex).first() | Some(a)} {a.name | Some(n)} =>
|
|
469
474
|
h.parameters.find {_.name == n}.map {_ => a.at}
|
|
470
475
|
| InferLookupHook h => Some(h.symbol.value.usageAt)
|
|
476
|
+
| InferRecordFieldHook h => Some(h.usageAt)
|
|
471
477
|
| _ => None
|
|
472
478
|
}.filter {at =>
|
|
473
479
|
!at.file.endsWith(">") &&
|
|
474
480
|
(includeDeclaration || at != definition.at)
|
|
475
481
|
}
|
|
482
|
+
|
|
483
|
+
//referencesResult.each {Log.trace(Show.show(_))}
|
|
476
484
|
|
|
477
485
|
let clientLocations = referencesResult.addAll(
|
|
478
486
|
if(includeDeclaration) {[definition.at]} else {[]}
|
|
@@ -535,16 +535,10 @@ const unification_ = ff_compiler_Unification.make_([], false);
|
|
|
535
535
|
const newGenerics_ = ff_core_List.List_map(constraint_.generics_, ((_w1) => {
|
|
536
536
|
return ff_compiler_Unification.Unification_instantiate(unification_, instantiationMap_, _w1)
|
|
537
537
|
}));
|
|
538
|
-
|
|
538
|
+
{
|
|
539
|
+
const _1 = ff_core_List.List_grabFirst(newGenerics_);
|
|
539
540
|
if(_1.TConstructor) {
|
|
540
|
-
const
|
|
541
|
-
return t_
|
|
542
|
-
}
|
|
543
|
-
if(_1.TVariable) {
|
|
544
|
-
const t_ = _1;
|
|
545
|
-
return ff_compiler_Dictionaries.fail_(t_.at_, " is still a unification variable")
|
|
546
|
-
}
|
|
547
|
-
}))(ff_core_List.List_grabFirst(newGenerics_));
|
|
541
|
+
const firstType_ = _1;
|
|
548
542
|
const instance_ = ff_core_Option.Option_else(ff_core_Map.Map_get(self_.instances_, ff_compiler_Unification.InstanceKey(constraint_.name_, firstType_.name_), ff_compiler_Unification.ff_core_Ordering_Order$ff_compiler_Unification_InstanceKey), (() => {
|
|
549
543
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Missing instance " + firstType_.name_) + ": ") + constraint_.name_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
550
544
|
}));
|
|
@@ -553,6 +547,12 @@ return ff_compiler_Dictionaries.Dictionaries_makeDictionary(self_, at_, instance
|
|
|
553
547
|
}));
|
|
554
548
|
return ff_compiler_Syntax.Dictionary(instance_.packagePair_, instance_.moduleName_, constraint_.name_, firstType_.name_, dictionaries_)
|
|
555
549
|
}
|
|
550
|
+
if(_1.TVariable) {
|
|
551
|
+
const t_ = _1;
|
|
552
|
+
return ff_compiler_Dictionaries.fail_(t_.at_, " is still a unification variable")
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
556
|
|
|
557
557
|
export async function Dictionaries_processModule$(self_, module_, otherModules_, $task) {
|
|
558
558
|
const environment_ = ff_compiler_Environment.make_(module_, otherModules_, true);
|
|
@@ -936,16 +936,10 @@ const unification_ = ff_compiler_Unification.make_([], false);
|
|
|
936
936
|
const newGenerics_ = ff_core_List.List_map(constraint_.generics_, ((_w1) => {
|
|
937
937
|
return ff_compiler_Unification.Unification_instantiate(unification_, instantiationMap_, _w1)
|
|
938
938
|
}));
|
|
939
|
-
|
|
939
|
+
{
|
|
940
|
+
const _1 = ff_core_List.List_grabFirst(newGenerics_);
|
|
940
941
|
if(_1.TConstructor) {
|
|
941
|
-
const
|
|
942
|
-
return t_
|
|
943
|
-
}
|
|
944
|
-
if(_1.TVariable) {
|
|
945
|
-
const t_ = _1;
|
|
946
|
-
return ff_compiler_Dictionaries.fail_(t_.at_, " is still a unification variable")
|
|
947
|
-
}
|
|
948
|
-
}))(ff_core_List.List_grabFirst(newGenerics_));
|
|
942
|
+
const firstType_ = _1;
|
|
949
943
|
const instance_ = ff_core_Option.Option_else(ff_core_Map.Map_get(self_.instances_, ff_compiler_Unification.InstanceKey(constraint_.name_, firstType_.name_), ff_compiler_Unification.ff_core_Ordering_Order$ff_compiler_Unification_InstanceKey), (() => {
|
|
950
944
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Missing instance " + firstType_.name_) + ": ") + constraint_.name_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
951
945
|
}));
|
|
@@ -954,6 +948,12 @@ return ff_compiler_Dictionaries.Dictionaries_makeDictionary(self_, at_, instance
|
|
|
954
948
|
}));
|
|
955
949
|
return ff_compiler_Syntax.Dictionary(instance_.packagePair_, instance_.moduleName_, constraint_.name_, firstType_.name_, dictionaries_)
|
|
956
950
|
}
|
|
951
|
+
if(_1.TVariable) {
|
|
952
|
+
const t_ = _1;
|
|
953
|
+
return ff_compiler_Dictionaries.fail_(t_.at_, " is still a unification variable")
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
957
|
|
|
958
958
|
export const ff_core_Any_HasAnyTag$ff_compiler_Dictionaries_Dictionaries = {
|
|
959
959
|
anyTag_() {
|