8000 Refactor implementation of lookupCompanion · scala/scala@8b827e2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8b827e2

Browse files
committed
Refactor implementation of lookupCompanion
1 parent 1d41aef commit 8b827e2

File tree

3 files changed

+44
-39
lines changed

3 files changed

+44
-39
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,27 +1193,48 @@ trait Contexts { self: Analyzer =>
11931193
res
11941194
}
11951195

1196-
final def lookupCompanionOf(original: Symbol): Symbol = {
1197-
if (original.isModuleClass) original.sourceModule
1198-
else lookupScopeEntry(original) match {
1199-
case null => NoSymbol
1200-
case entry => entry.owner.lookupCompanion(original)
1196+
final def lookupCompanionInIncompleteOwner(original: Symbol): Symbol = {
1197+
def lookupCodefinedCompanion(scope: Scope, original: Symbol): Symbol = {
1198+
val companionName = original.name.companionName
1199+
scope.lookupSymbolEntry(original) match {
1200+
case null =>
1201+
case entry =>
1202+
var e = scope.lookupEntry(companionName)
1203+
while (e != null) {
1204+
// 1) Must be owned by the same Scope, to ensure that in
1205+
// `{ class C; { ...; object C } }`, the class is not seen as a companion of the object.
1206+
// 2) Must be a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions.
1207+
def isClassAndModule(sym1: Symbol, sym2: Symbol) = sym1.isClass && sym2.isModule || sym2.isModule && sym1.isClass
1208+
if ((e.owner eq entry.owner) && isClassAndModule(original, e.sym)) {
1209+
val isCodefined = e.sym.isCoDefinedWith(original)
1210+
return if (isCodefined) e.sym else NoSymbol
1211+
}
1212+
e = scope.lookupNextEntry(e)
1213+
}
1214+
}
1215+
NoSymbol
12011216
}
1202-
}
12031217

1204-
/** Search scopes in current and enclosing contexts for the definition of `symbol` */
1205-
private def lookupScopeEntry(symbol: Symbol): ScopeEntry = {
1206-
var res: ScopeEntry = null
1207-
var ctx = this
1208-
while (res == null && ctx.outer != ctx) {
1209-
val s = ctx.scope lookupSymbolEntry symbol
1210-
if (s != null)
1211-
res = s
1212-
else
1213-
ctx = ctx.outer
1218+
/* Search scopes in current and enclosing contexts for the definition of `symbol` */
1219+
def lookupScopeEntry(symbol: Symbol): ScopeEntry = {
1220+
var res: ScopeEntry = null
1221+
var ctx = this
1222+
while (res == null && ctx.outer != ctx) {
1223+
val s = ctx.scope lookupSymbolEntry symbol
1224+
if (s != null)
1225+
res = s
1226+
else
1227+
ctx = ctx.outer
1228+
}
1229+
res
1230+
}
1231+
1232+
lookupScopeEntry(original) match {
1233+
case null => NoSymbol
1234+
case entry => lookupCodefinedCompanion(entry.owner, original)
12141235
}
1215-
res
12161236
}
1237+
12171238
} //class Context
12181239

12191240
/** A `Context` focussed on an `Import` tree */

src/compiler/scala/tools/nsc/typechecker/Namers.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,9 +1955,12 @@ trait Namers extends MethodSynthesis {
19551955
// Doing this generally would trigger cycles; that's what we also
19561956
// use the lower-level scan through the current Context as a fall back.
19571957
if (!currentRun.compiles(owner)) owner.initialize
1958-
original.companionSymbol orElse {
1959-
ctx.lookupCompanionOf(original)
1960-
}
1958+
1959+
if (original.isModuleClass) original.sourceModule
1960+
else if (!owner.isTerm && owner.hasCompleteInfo)
1961+
original.companionSymbol
1962+
else
1963+
ctx.lookupCompanionInIncompleteOwner(original)
19611964
}
19621965

19631966
/** A version of `Symbol#linkedClassOfClass` that works with local companions, ala `companionSymbolOf`. */

src/reflect/scala/reflect/internal/Scopes.scala

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -291,25 +291,6 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
291291
null
292292
}
293293

294-
final def lookupCompanion(original: Symbol): Symbol = {
295-
lookupSymbolEntry(original) match {
296-
case null =>
297-
case entry =>
298-
var e = lookupEntry(original.name.companionName)
299-
while (e != null) {
300-
// 1) Must be owned by the same Scope, to ensure that in
301-
// `{ class C; { ...; object C } }`, the class is not seen as a comaniopn of the object.
302-
// 2) Must be a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions.
303-
def isClassAndModule(sym1: Symbol, sym2: Symbol) = sym1.isClass && sym2.isModule
304-
if ((e.owner eq entry.owner) && (isClassAndModule(original, e.sym) || isClassAndModule(e.sym, original))) {
305-
return if (e.sym.isCoDefinedWith(original)) e.sym else NoSymbol
306-
}
307-
e = lookupNextEntry(e)
308-
}
309-
}
310-
NoSymbol
311-
}
312-
313294
/** lookup a symbol entry matching given name.
314295
* @note from Martin: I believe this is a hotspot or will be one
315296
* in future versions of the type system. I have reverted the previous

0 commit comments

Comments
 (0)
0