diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-06-06 14:29:05 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-06-08 15:32:03 +0200 |
commit | 6355d1a0b825c99560d4ccec1a8769f7421b1a71 (patch) | |
tree | 80f448f0da11dcab9cee30f3d8fe867cd66313ed /src/compiler/scala/reflect/reify/States.scala | |
parent | ce67870e64afabf75363679bcee597812ad223e9 (diff) | |
download | scala-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.scala | 65 |
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 + } + } +} |