diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-07-27 01:38:45 -0700 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-07-27 14:09:39 -0700 |
commit | e5121c888239b3a18ea7b341981d41bb4c9a1c07 (patch) | |
tree | baf179d23d2901cae7a9400307e623f0472c42bd /src/compiler | |
parent | ced7214959c05eb5fcf55b79f4a6691d2d8dc987 (diff) | |
download | scala-e5121c888239b3a18ea7b341981d41bb4c9a1c07.tar.gz scala-e5121c888239b3a18ea7b341981d41bb4c9a1c07.tar.bz2 scala-e5121c888239b3a18ea7b341981d41bb4c9a1c07.zip |
Remove dependency on typer phase in ClassfileParser.
ClassfileParser depends on forcing infos during typer phase.
It's not entirely clear why this is needed (git blame doesn't
help much) but I decided to preserve the logic.
Therefore, I introduced an abstract method called
`lookupMemberAtTyperPhaseIfPossible` which preserves the original
semantics but is implemented outside of ClassfileParser so the
ClassfileParser itself doesn't need to depend on typer phase and
phase mutation utilities.
I removed `loaders` override in `test/files/presentation/doc`.
I would have to update it to implement the
`lookupMemberAtTyperPhaseIfPossible` method. However, the override
doesn't seem to be doing anything useful so I just removed it.
Diffstat (limited to 'src/compiler')
5 files changed, 53 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index ea6543bb71..ee03aa1ac2 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -356,6 +356,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter) lazy val loaders = new SymbolLoaders { val global: Global.this.type = Global.this + def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = { + def lookup = sym.info.member(name) + // if loading during initialization of `definitions` typerPhase is not yet set. + // in that case we simply load the member at the current phase + if (currentRun.typerPhase eq null) + lookup + else + enteringTyper { lookup } + } } /** Returns the mirror that loaded given symbol */ diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala index 3f2141782a..1fd24d4e1f 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala @@ -108,6 +108,16 @@ abstract class ICodes extends AnyRef object icodeReader extends ICodeReader { lazy val global: ICodes.this.global.type = ICodes.this.global + import global._ + def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = { + def lookup = sym.info.member(name) + // if loading during initialization of `definitions` typerPhase is not yet set. + // in that case we simply load the member at the current phase + if (currentRun.typerPhase eq null) + lookup + else + enteringTyper { lookup } + } } /** A phase which works on icode. */ diff --git a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala index 4e4efef607..f93be78a3f 100644 --- a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala @@ -17,6 +17,20 @@ abstract class BrowsingLoaders extends SymbolLoaders { import syntaxAnalyzer.{OutlineParser, MalformedInput} + /* + * BrowsingLoaders has dependency on Global so we can implement this method here instead of forcing subclasses + * of BrowsingLoaders (e.g. in interactive) to implement it. + */ + override def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = { + def lookup = sym.info.member(name) + // if loading during initialization of `definitions` typerPhase is not yet set. + // in that case we simply load the member at the current phase + if (currentRun.typerPhase eq null) + lookup + else + enteringTyper { lookup } + } + /** In browse mode, it can happen that an encountered symbol is already * present. For instance, if the source file has a name different from * the classes and objects it contains, the symbol loader will always diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index bd157ed691..ac38e24787 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -22,6 +22,11 @@ import scala.reflect.io.{ AbstractFile, NoAbstractFile } abstract class SymbolLoaders { val global: Global import global._ + + /** + * Required by ClassfileParser. Check documentation in that class for details. + */ + protected def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol import SymbolLoadersStats._ protected def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader): Symbol = { @@ -249,6 +254,8 @@ abstract class SymbolLoaders { } with ClassfileParser { override protected type ThisConstantPool = ConstantPool override protected def newConstantPool: ThisConstantPool = new ConstantPool + override protected def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = + SymbolLoaders.this.lookupMemberAtTyperPhaseIfPossible(sym, name) } protected def description = "class file "+ classfile.toString diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index e8abeb7674..4743260c79 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -26,6 +26,17 @@ import scala.tools.nsc.io.AbstractFile abstract class ClassfileParser { val global: Global import global._ + + /** + * If typer phase is defined then perform member lookup of a symbol + * `sym` at typer phase. This method results from refactoring. The + * original author of the logic that uses typer phase didn't explain + * why we need to force infos at that phase specifically. It only mentioned + * that ClassfileParse can be called late (e.g. at flatten phase) and + * we make to make sure we handle such situation properly. + */ + protected def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol + import definitions._ import scala.reflect.internal.ClassfileConstants._ import Flags._ @@ -1093,19 +1104,15 @@ abstract class ClassfileParser { case Some(entry) => innerSymbol(entry) case _ => NoSymbol } - // if loading during initialization of `definitions` typerPhase is not yet set. - // in that case we simply load the member at the current phase - @inline private def enteringTyperIfPossible(body: => Symbol): Symbol = - if (currentRun.typerPhase eq null) body else enteringTyper(body) private def innerSymbol(entry: InnerClassEntry): Symbol = { val name = entry.originalName.toTypeName val enclosing = entry.enclosing def getMember = ( if (enclosing == clazz) entry.scope lookup name - else enclosing.info member name + else lookupMemberAtTyperPhaseIfPossible(enclosing, name) ) - enteringTyperIfPossible(getMember) + getMember /* There used to be an assertion that this result is not NoSymbol; changing it to an error * revealed it had been going off all the time, but has been swallowed by a catch t: Throwable * in Repository.scala. Since it has been accomplishing nothing except misleading anyone who |