@@ -59,17 +59,28 @@ trait Importers extends api.Importers { to: SymbolTable =>
5959
6060 // ============== SYMBOLS ==============
6161
62- protected def recreatedSymbolCompleter (their : from.Symbol ) = {
63- val mytypeParams = their.typeParams map importSymbol
64- new LazyPolyType (mytypeParams) with FlagAgnosticCompleter {
65- override def complete (my : to.Symbol ): Unit = {
66- val theirCore = their.info match {
67- case from.PolyType (_, core) => core
68- case core => core
62+ protected def recreatedSymbolCompleter (my : to.Symbol , their : from.Symbol ) = {
63+ // we lock the symbol that is imported for a very short period of time
64+ // i.e. only for when type parameters of the symbol are being imported
65+ // the lock is used to communicate to the recursive importSymbol calls
66+ // that type parameters need to be created from scratch
67+ // because otherwise type parameters are imported by looking into owner.typeParams
68+ // which is obviously unavailable while the completer is being created
69+ try {
70+ my setFlag Flags .LOCKED
71+ val mytypeParams = their.typeParams map importSymbol
72+ new LazyPolyType (mytypeParams) with FlagAgnosticCompleter {
73+ override def complete (my : to.Symbol ): Unit = {
74+ val theirCore = their.info match {
75+ case from.PolyType (_, core) => core
76+ case core => core
77+ }
78+ my setInfo GenPolyType (mytypeParams, importType(theirCore))
79+ my setAnnotations (their.annotations map importAnnotationInfo)
6980 }
70- my setInfo GenPolyType (mytypeParams, importType(theirCore))
71- my setAnnotations (their.annotations map importAnnotationInfo)
7281 }
82+ } finally {
83+ my resetFlag Flags .LOCKED
7384 }
7485 }
7586
@@ -121,9 +132,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
121132 myowner.newTypeSymbol(myname.toTypeName, mypos, myflags)
122133 }
123134 symMap.weakUpdate(their, my)
124- my setFlag Flags .LOCKED
125- my setInfo recreatedSymbolCompleter(their)
126- my resetFlag Flags .LOCKED
135+ my setInfo recreatedSymbolCompleter(my, their)
127136 }
128137
129138 def importSymbol (their0 : from.Symbol ): Symbol = {
@@ -142,53 +151,50 @@ trait Importers extends api.Importers { to: SymbolTable =>
142151 else if (their.isRoot)
143152 rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror
144153 else {
154+ val isModuleClass = their.isModuleClass
155+ val isTparam = their.isTypeParameter && their.paramPos >= 0
156+ val isOverloaded = their.isOverloaded
157+
145158 var theirscope = if (their.owner.isClass && ! their.owner.isRefinementClass) their.owner.info else from.NoType
146- var theirexisting = theirscope.decl(their.name)
147- if (their.isModuleClass) theirexisting = theirexisting.moduleClass
159+ val theirexisting = if (isModuleClass) theirscope.decl(their.name).moduleClass else theirscope.decl(their.name)
148160 if (! theirexisting.exists) theirscope = from.NoType
149161
150162 val myname = importName(their.name)
151163 val myowner = importSymbol(their.owner)
152164 val myscope = if (theirscope != from.NoType && ! (myowner hasFlag Flags .LOCKED )) myowner.info else NoType
153- var myexisting = if (myscope != NoType ) myscope.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods
154-
155- if (their.isModuleClass)
156- myexisting = importSymbol(their.sourceModule).moduleClass
157-
158- if (! their.isOverloaded && myexisting.isOverloaded) {
159- myexisting =
160- if (their.isMethod) {
161- val localCopy = cachedRecreateSymbol(their)
162- myexisting filter (_.tpe matches localCopy.tpe)
163- } else {
164- myexisting filter (! _.isMethod)
165+ val myexisting = {
166+ if (isModuleClass) importSymbol(their.sourceModule).moduleClass
167+ else if (isTparam) (if (myowner hasFlag Flags .LOCKED ) NoSymbol else myowner.typeParams(their.paramPos))
168+ else if (isOverloaded) myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol)
169+ else {
170+ def disambiguate (my : Symbol ) = {
171+ val result =
172+ if (their.isMethod) {
173+ val localCopy = cachedRecreateSymbol(their)
174+ my filter (_.tpe matches localCopy.tpe)
175+ } else {
176+ my filter (! _.isMethod)
177+ }
178+ assert(! result.isOverloaded,
179+ " import failure: cannot determine unique overloaded method alternative from\n " +
180+ (result.alternatives map (_.defString) mkString " \n " )+ " \n that matches " + their+ " :" + their.tpe)
181+ result
165182 }
166- assert(! myexisting.isOverloaded,
167- " import failure: cannot determine unique overloaded method alternative from\n " +
168- (myexisting.alternatives map (_.defString) mkString " \n " )+ " \n that matches " + their+ " :" + their.tpe)
183+
184+ val myexisting = if (myscope != NoType ) myscope.decl(myname) else NoSymbol
185+ if (myexisting.isOverloaded) disambiguate(myexisting)
186+ else myexisting
187+ }
169188 }
170189
171- val my = {
172- if (their.isOverloaded) {
173- myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol)
174- } else if (their.isTypeParameter && their.paramPos >= 0 && ! (myowner hasFlag Flags .LOCKED )) {
175- assert(myowner.typeParams.length > their.paramPos,
176- " import failure: cannot determine parameter " + their+ " (#" + their.paramPos+ " ) in " +
177- myowner+ typeParamsString(myowner.rawInfo)+ " \n original symbol was: " +
178- their.owner+ from.typeParamsString(their.owner.info))
179- myowner.typeParams(their.paramPos)
180- } else {
181- myexisting.orElse {
182- val my = cachedRecreateSymbol(their)
183- if (myscope != NoType ) {
184- assert(myscope.decls.lookup(myname) == NoSymbol , myname+ " " + myscope.decl(myname)+ " " + myexisting)
185- myscope.decls enter my
186- }
187- my
188- }
190+ myexisting.orElse {
191+ val my = cachedRecreateSymbol(their)
192+ if (myscope != NoType ) {
193+ assert(myscope.decls.lookup(myname) == NoSymbol , myname+ " " + myscope.decl(myname)+ " " + myexisting)
194+ myscope.decls enter my
189195 }
196+ my
190197 }
191- my
192198 }
193199 } // end recreateOrRelink
194200
0 commit comments