summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-05-28 11:06:43 +0200
committerEugene Burmako <xeno.by@gmail.com>2013-06-02 21:58:37 +0200
commitb136b42d43a8d745848e58a4dbba57d866bdc2cc (patch)
tree61e4c67f34fb3a3b0bbd8e72d38dc477800c4f0d /src
parentd5bfbd597e5fd4707b322c8bc13fd57f084ff1e4 (diff)
downloadscala-b136b42d43a8d745848e58a4dbba57d866bdc2cc.tar.gz
scala-b136b42d43a8d745848e58a4dbba57d866bdc2cc.tar.bz2
scala-b136b42d43a8d745848e58a4dbba57d866bdc2cc.zip
more refactoring and explanations in importers
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala102
1 files changed, 54 insertions, 48 deletions
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index ae1c2a9a77..f8584ac9b0 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -59,17 +59,28 @@ trait Importers extends api.Importers { to: SymbolTable =>
// ============== SYMBOLS ==============
- protected def recreatedSymbolCompleter(their: from.Symbol) = {
- val mytypeParams = their.typeParams map importSymbol
- new LazyPolyType(mytypeParams) with FlagAgnosticCompleter {
- override def complete(my: to.Symbol): Unit = {
- val theirCore = their.info match {
- case from.PolyType(_, core) => core
- case core => core
+ protected def recreatedSymbolCompleter(my: to.Symbol, their: from.Symbol) = {
+ // we lock the symbol that is imported for a very short period of time
+ // i.e. only for when type parameters of the symbol are being imported
+ // the lock is used to communicate to the recursive importSymbol calls
+ // that type parameters need to be created from scratch
+ // because otherwise type parameters are imported by looking into owner.typeParams
+ // which is obviously unavailable while the completer is being created
+ try {
+ my setFlag Flags.LOCKED
+ val mytypeParams = their.typeParams map importSymbol
+ new LazyPolyType(mytypeParams) with FlagAgnosticCompleter {
+ override def complete(my: to.Symbol): Unit = {
+ val theirCore = their.info match {
+ case from.PolyType(_, core) => core
+ case core => core
+ }
+ my setInfo GenPolyType(mytypeParams, importType(theirCore))
+ my setAnnotations (their.annotations map importAnnotationInfo)
}
- my setInfo GenPolyType(mytypeParams, importType(theirCore))
- my setAnnotations (their.annotations map importAnnotationInfo)
}
+ } finally {
+ my resetFlag Flags.LOCKED
}
}
@@ -121,9 +132,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
myowner.newTypeSymbol(myname.toTypeName, mypos, myflags)
}
symMap.weakUpdate(their, my)
- my setFlag Flags.LOCKED
- my setInfo recreatedSymbolCompleter(their)
- my resetFlag Flags.LOCKED
+ my setInfo recreatedSymbolCompleter(my, their)
}
def importSymbol(their0: from.Symbol): Symbol = {
@@ -142,53 +151,50 @@ trait Importers extends api.Importers { to: SymbolTable =>
else if (their.isRoot)
rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror
else {
+ val isModuleClass = their.isModuleClass
+ val isTparam = their.isTypeParameter && their.paramPos >= 0
+ val isOverloaded = their.isOverloaded
+
var theirscope = if (their.owner.isClass && !their.owner.isRefinementClass) their.owner.info else from.NoType
- var theirexisting = theirscope.decl(their.name)
- if (their.isModuleClass) theirexisting = theirexisting.moduleClass
+ val theirexisting = if (isModuleClass) theirscope.decl(their.name).moduleClass else theirscope.decl(their.name)
if (!theirexisting.exists) theirscope = from.NoType
val myname = importName(their.name)
val myowner = importSymbol(their.owner)
val myscope = if (theirscope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType
- var myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods
-
- if (their.isModuleClass)
- myexisting = importSymbol(their.sourceModule).moduleClass
-
- if (!their.isOverloaded && myexisting.isOverloaded) {
- myexisting =
- if (their.isMethod) {
- val localCopy = cachedRecreateSymbol(their)
- myexisting filter (_.tpe matches localCopy.tpe)
- } else {
- myexisting filter (!_.isMethod)
+ val myexisting = {
+ if (isModuleClass) importSymbol(their.sourceModule).moduleClass
+ else if (isTparam) (if (myowner hasFlag Flags.LOCKED) NoSymbol else myowner.typeParams(their.paramPos))
+ else if (isOverloaded) myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol)
+ else {
+ def disambiguate(my: Symbol) = {
+ val result =
+ if (their.isMethod) {
+ val localCopy = cachedRecreateSymbol(their)
+ my filter (_.tpe matches localCopy.tpe)
+ } else {
+ my filter (!_.isMethod)
+ }
+ assert(!result.isOverloaded,
+ "import failure: cannot determine unique overloaded method alternative from\n "+
+ (result.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe)
+ result
}
- assert(!myexisting.isOverloaded,
- "import failure: cannot determine unique overloaded method alternative from\n "+
- (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe)
+
+ val myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol
+ if (myexisting.isOverloaded) disambiguate(myexisting)
+ else myexisting
+ }
}
- val my = {
- if (their.isOverloaded) {
- myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol)
- } else if (their.isTypeParameter && their.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) {
- assert(myowner.typeParams.length > their.paramPos,
- "import failure: cannot determine parameter "+their+" (#"+their.paramPos+") in "+
- myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+
- their.owner+from.typeParamsString(their.owner.info))
- myowner.typeParams(their.paramPos)
- } else {
- myexisting.orElse {
- val my = cachedRecreateSymbol(their)
- if (myscope != NoType) {
- assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting)
- myscope.decls enter my
- }
- my
- }
+ myexisting.orElse {
+ val my = cachedRecreateSymbol(their)
+ if (myscope != NoType) {
+ assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting)
+ myscope.decls enter my
}
+ my
}
- my
}
} // end recreateOrRelink