blob: 65f3f424e8c64efd7c613d44a1b39d94dc00b58c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package scala.reflect.reify
trait States {
self: Reifier =>
import global._
/** Encapsulates reifier state
*
* When untangling reifier symbol tables from the reifier itself,
* I discovered that encoding of a symbol table (e.g. producing corresponding reificode)
* might cause subsequent reification (e.g. when filling in signatures and annotations for syms).
*
* This is a mess in the face of nested reifications, splices and inlining of thereof,
* so I made `SymbolTable` immutable, which brought a significant amount of sanity.
*
* However that wasn't enough. Sure, symbol table became immutable, but the reifier still needed
* to mutate its `symtab` field during reification. This caused nasty desyncs between the table being encoded
* and the table of the underlying reifier, so I decided to encapsulate the entire state here,
* so that encoding can backup the state before it starts and restore it after it completes.
*/
val state = new State
// todo. rewrite the reifier so that we don't need mutable state anymore
// to aid you with that I've already removed all the setters from the reifier
// so all the places that involve mutations are forced to do that by explicitly mentioning `state`
class State {
var symtab = SymbolTable()
var reifyTreeSymbols = false
var reifyTreeTypes = false
private var _reificationIsConcrete = true
def reificationIsConcrete: Boolean = _reificationIsConcrete
def reificationIsConcrete_=(value: Boolean): Unit = {
_reificationIsConcrete = value
if (!value && concrete) {
current match {
case tpe: Type => CannotReifyWeakType(s" having unresolved type parameter $tpe")
case sym: Symbol => CannotReifyWeakType(s" referring to ${sym.kindString} ${sym.fullName} local to the reifee")
case _ => CannotReifyWeakType("")
}
}
}
var reifyStack = reifee :: Nil
var localSymbols = Map[Symbol, Int]()
def backup: State = {
val backup = new State
backup.symtab = this.symtab
backup.reifyTreeSymbols = this.reifyTreeSymbols
backup.reifyTreeTypes = this.reifyTreeTypes
backup._reificationIsConcrete = this._reificationIsConcrete
backup.reifyStack = this.reifyStack
backup.localSymbols = this.localSymbols
backup
}
def restore(backup: State): Unit = {
this.symtab = backup.symtab
this.reifyTreeSymbols = backup.reifyTreeSymbols
this.reifyTreeTypes = backup.reifyTreeTypes
this._reificationIsConcrete = backup._reificationIsConcrete
this.reifyStack = backup.reifyStack
this.localSymbols = backup.localSymbols
}
}
}
|