Skip to content

Commit 8f020bb

Browse files
committed
Fix #536 - only load member classes of classes that are currently compiled.
It seems wasteful to load the member classes even of classes that are not currently compiled. It also makes us vulnerable to any misinterpretation of Java file formats. In th particular case of #536, we parsed a class an anonymous Collection$1 which was referring to the type parameter of its enclosing class, but was not diagnosed as an inner class of the enclosing class.
1 parent a52ca60 commit 8f020bb

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,24 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
678678

679679
// members
680680
def primaryConstructor: Symbol = toDenot(sym).primaryConstructor
681-
def nestedClasses: List[Symbol] = memberClasses //exitingPhase(currentRun.lambdaliftPhase)(sym.memberClasses)
682-
def memberClasses: List[Symbol] = toDenot(sym).info.memberClasses.map(_.symbol).toList
681+
682+
/** For currently compiled classes: All locally defined classes including local classes.
683+
* The empty list for classes that are not currently compiled.
684+
*/
685+
def nestedClasses: List[Symbol] = localClasses(ctx.flattenPhase)
686+
687+
/** For currently compiled classes: All classes that are declared as members of this class
688+
* (but not inherited ones). The empty list for classes that are not currently compiled.
689+
*/
690+
def memberClasses: List[Symbol] = localClasses(ctx.lambdaLiftPhase)
691+
692+
private def localClasses(phase: Phase) =
693+
if (sym.isDefinedInCurrentRun)
694+
ctx.atPhase(phase) { implicit ctx =>
695+
toDenot(sym).info.decls.filter(_.isClass).toList
696+
}
697+
else Nil
698+
683699
def annotations: List[Annotation] = Nil
684700
def companionModuleMembers: List[Symbol] = {
685701
// phase travel to exitingPickler: this makes sure that memberClassesOf only sees member classes,

src/dotty/tools/dotc/core/Phases.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ object Phases {
235235
private val extensionMethodsCache = new PhaseCache(classOf[ExtensionMethods])
236236
private val erasureCache = new PhaseCache(classOf[Erasure])
237237
private val patmatCache = new PhaseCache(classOf[PatternMatcher])
238+
private val lambdaLiftCache = new PhaseCache(classOf[LambdaLift])
238239
private val flattenCache = new PhaseCache(classOf[Flatten])
239240
private val explicitOuterCache = new PhaseCache(classOf[ExplicitOuter])
240241
private val gettersCache = new PhaseCache(classOf[Getters])
@@ -245,6 +246,7 @@ object Phases {
245246
def extensionMethodsPhase = extensionMethodsCache.phase
246247
def erasurePhase = erasureCache.phase
247248
def patmatPhase = patmatCache.phase
249+
def lambdaLiftPhase = lambdaLiftCache.phase
248250
def flattenPhase = flattenCache.phase
249251
def explicitOuterPhase = explicitOuterCache.phase
250252
def gettersPhase = gettersCache.phase

tests/pos/i536.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Max {
2+
java.util.Collections.max(null)
3+
}

0 commit comments

Comments
 (0)