summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/reify/States.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-06-06 14:29:05 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:32:03 +0200
commit6355d1a0b825c99560d4ccec1a8769f7421b1a71 (patch)
tree80f448f0da11dcab9cee30f3d8fe867cd66313ed /src/compiler/scala/reflect/reify/States.scala
parentce67870e64afabf75363679bcee597812ad223e9 (diff)
downloadscala-6355d1a0b825c99560d4ccec1a8769f7421b1a71.tar.gz
scala-6355d1a0b825c99560d4ccec1a8769f7421b1a71.tar.bz2
scala-6355d1a0b825c99560d4ccec1a8769f7421b1a71.zip
brings reification up to speed
Along with recovering from reflection refactoring, I implemented some new features (e.g. rollback of macro expansions), and did some stabilizing refactorings (e.g. moved mutable state into a ghetto). Also used the refactoring as a chance to fix free and aux symbols. Encapsulated this notion in a symbol table class, which allowed me to address outstanding issues with symbol table inheritance and inlining.
Diffstat (limited to 'src/compiler/scala/reflect/reify/States.scala')
-rw-r--r--src/compiler/scala/reflect/reify/States.scala65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/compiler/scala/reflect/reify/States.scala b/src/compiler/scala/reflect/reify/States.scala
new file mode 100644
index 0000000000..97b703d32b
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/States.scala
@@ -0,0 +1,65 @@
+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) {
+ assert(current.isInstanceOf[Type], current)
+ val offender = current.asInstanceOf[Type]
+ CannotReifyConcreteTypeTagHavingUnresolvedTypeParameters(offender)
+ }
+ }
+ 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
+ }
+ }
+}