scala.reflect.reify.States.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
package scala.reflect.reify
trait States {
self: Reifier =>
import global._
import definitions._
/** 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 local ${sym.kindString} ${sym.fullName}")
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
}
}
}