Skip to content

Commit f79679f

Browse files
committed
Split half of BackendIntf.originalOwner into originalLexicallyEnclosingClass.
The logic in `originalOwner` was not only looking up the original owner, but also going further to the enclosing class of that owner, so the name was pretty misleading. This commit separates the two operations in two methods. The actual `originalOwner` half of it is extracted in `SymDenotations`, as it will be needed by the Scala.js back-end as well.
1 parent 944b6b3 commit f79679f

File tree

5 files changed

+34
-18
lines changed

5 files changed

+34
-18
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeAsmCommon.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import interface._
2020
// Here used to be an `assert(!classSym.isDelambdafyFunction)`: delambdafy lambda classes are
2121
// always top-level. However, SI-8900 shows an example where the weak name-based implementation
2222
// of isDelambdafyFunction failed (for a function declared in a package named "lambda").
23-
classSym.isAnonymousClass || (classSym.originalOwner != NoSymbol && !classSym.originalOwner.isClass)
23+
classSym.isAnonymousClass || {
24+
val originalOwnerLexicallyEnclosingClass = classSym.originalOwner.originalLexicallyEnclosingClass
25+
originalOwnerLexicallyEnclosingClass != NoSymbol && !originalOwnerLexicallyEnclosingClass.isClass
26+
}
2427
}
2528

2629
/**
@@ -51,9 +54,9 @@ import interface._
5154
def enclosingMethod(sym: Symbol): Option[Symbol] = {
5255
if (sym.isClass || sym == NoSymbol) None
5356
else if (sym.isMethod) Some(sym)
54-
else enclosingMethod(sym.originalOwner)
57+
else enclosingMethod(sym.originalOwner.originalLexicallyEnclosingClass)
5558
}
56-
enclosingMethod(classSym.originalOwner)
59+
enclosingMethod(classSym.originalOwner.originalLexicallyEnclosingClass)
5760
}
5861

5962
/**
@@ -64,9 +67,9 @@ import interface._
6467
assert(classSym.isClass, classSym)
6568
def enclosingClass(sym: Symbol): Symbol = {
6669
if (sym.isClass) sym
67-
else enclosingClass(sym.originalOwner)
70+
else enclosingClass(sym.originalOwner.originalLexicallyEnclosingClass)
6871
}
69-
enclosingClass(classSym.originalOwner)
72+
enclosingClass(classSym.originalOwner.originalLexicallyEnclosingClass)
7073
}
7174

7275
/*final*/ case class EnclosingMethodEntry(owner: String, name: String, methodDescriptor: String)

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes {
147147
if (!isNested) None
148148
else {
149149
// See comment in BTypes, when is a class marked static in the InnerClass table.
150-
val isStaticNestedClass = innerClassSym.originalOwner.isOriginallyStaticOwner
150+
val isStaticNestedClass = innerClassSym.originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner
151151

152152
// After lambdalift (which is where we are), the rawowoner field contains the enclosing class.
153153
val enclosingClassSym = innerClassSym.enclosingClassSym

compiler/src/dotty/tools/backend/jvm/BackendInterface.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
537537
def companionSymbol: Symbol
538538
def moduleClass: Symbol
539539
def enclosingClassSym: Symbol
540+
def originalLexicallyEnclosingClass: Symbol
540541
def nextOverriddenSymbol: Symbol
541542

542543

@@ -584,7 +585,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
584585
* the owner of U is T, so UModuleClass.isStatic is true. Phase travel does not help here.
585586
*/
586587
def isOriginallyStaticOwner: Boolean =
587-
isPackageClass || isModuleClass && originalOwner.isOriginallyStaticOwner
588+
isPackageClass || isModuleClass && originalOwner.originalLexicallyEnclosingClass.isOriginallyStaticOwner
588589

589590
def samMethod(): Symbol
590591

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -727,18 +727,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
727727
// navigation
728728
def owner: Symbol = toDenot(sym).owner
729729
def rawowner: Symbol = {
730-
originalOwner
730+
originalOwner.originalLexicallyEnclosingClass
731731
}
732-
def originalOwner: Symbol =
733-
// used to populate the EnclosingMethod attribute.
734-
// it is very tricky in presence of classes(and annonymous classes) defined inside supper calls.
735-
if (sym.exists) {
736-
val original = toDenot(sym).initial
737-
val validity = original.validFor
738-
val shiftedContext = ctx.withPhase(validity.phaseId)
739-
val r = toDenot(sym)(shiftedContext).maybeOwner.lexicallyEnclosingClass(shiftedContext)
740-
r
741-
} else NoSymbol
732+
def originalOwner: Symbol = toDenot(sym).originalOwner
742733
def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol)
743734
def superClass: Symbol = {
744735
val t = toDenot(sym).asClass.superClass
@@ -765,6 +756,18 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
765756
}
766757
else sym.enclosingClass(ctx.withPhase(ctx.flattenPhase.prev))
767758
} //todo is handled specially for JavaDefined symbols in scalac
759+
def originalLexicallyEnclosingClass: Symbol =
760+
// used to populate the EnclosingMethod attribute.
761+
// it is very tricky in presence of classes(and annonymous classes) defined inside supper calls.
762+
if (sym.exists) {
763+
/* This logic is similar to SymDenotations.originalOwner, but it cannot
764+
* easily be factored out because we need the `shiftedContext` when calling
765+
* `lexicallyEnclosingClass`.
766+
*/
767+
val validity = toDenot(sym).initial.validFor
768+
val shiftedContext = ctx.withPhase(validity.phaseId)
769+
toDenot(sym)(shiftedContext).lexicallyEnclosingClass(shiftedContext)
770+
} else NoSymbol
768771
def nextOverriddenSymbol: Symbol = toDenot(sym).nextOverriddenSymbol
769772

770773
// members

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,15 @@ object SymDenotations {
399399
/** The name with which the denoting symbol was created */
400400
final def originalName(implicit ctx: Context): Name = initial.effectiveName
401401

402+
/** The owner with which the denoting symbol was created. */
403+
final def originalOwner(implicit ctx: Context): Symbol =
404+
if (exists) {
405+
// There is a similar logic in DottyBackendInterface.originalLexicallyEnclosingClass (see comment there)
406+
val validity = initial.validFor
407+
val shiftedContext = ctx.withPhase(validity.phaseId)
408+
Symbols.toDenot(symbol)(shiftedContext).maybeOwner
409+
} else NoSymbol
410+
402411
/** The encoded full path name of this denotation, where outer names and inner names
403412
* are separated by `separator` strings as indicated by the given name kind.
404413
* Drops package objects. Represents each term in the owner chain by a simple `_$`.

0 commit comments

Comments
 (0)