@@ -2,8 +2,8 @@ package dotty.tools.dotc
22package core
33
44import Contexts ._ , Symbols ._ , Types ._ , Flags ._ , Scopes ._ , Decorators ._ , NameOps ._
5- import Denotations ._
6- import SymDenotations . LazyType , Names .Name , StdNames .nme
5+ import Denotations ._ , SymDenotations . _
6+ import Names .Name , StdNames .nme
77import ast .untpd
88
99/** Extension methods for contexts where we want to keep the ctx.<methodName> syntax */
@@ -34,14 +34,51 @@ object ContextOps:
3434 if (elem.name == name) return elem.sym.denot // return self
3535 }
3636 val pre = ctx.owner.thisType
37- pre.findMember(name, pre, required, excluded)
37+ if ctx.isJava then javaFindMember(name, pre, required, excluded)
38+ else pre.findMember(name, pre, required, excluded)
3839 }
3940 else // we are in the outermost context belonging to a class; self is invisible here. See inClassContext.
4041 ctx.owner.findMember(name, ctx.owner.thisType, required, excluded)
4142 else
4243 ctx.scope.denotsNamed(name).filterWithFlags(required, excluded).toDenot(NoPrefix )
4344 }
4445
46+ final def javaFindMember (name : Name , pre : Type , required : FlagSet = EmptyFlags , excluded : FlagSet = EmptyFlags ): Denotation =
47+ assert(ctx.isJava)
48+ inContext(ctx) {
49+
50+ val preSym = pre.typeSymbol
51+
52+ // 1. Try to search in current type and parents
53+ val directSearch = pre.findMember(name, pre, required, excluded)
54+
55+ // 2. Try to search in companion class if current is an object
56+ def searchCompanionClass = if preSym.is(Flags .Module ) then
57+ preSym.companionClass.thisType.findMember(name, pre, required, excluded)
58+ else NoDenotation
59+
60+ // 3. Try to search in companion objects of super classes.
61+ // In Java code, static inner classes, which we model as members of the companion object,
62+ // can be referenced from an ident in a subclass or by a selection prefixed by the subclass.
63+ def searchSuperCompanionObjects =
64+ val toSearch = if preSym.is(Flags .Module ) then
65+ if preSym.companionClass.exists then
66+ preSym.companionClass.asClass.baseClasses
67+ else Nil
68+ else
69+ preSym.asClass.baseClasses
70+
71+ toSearch.iterator.map { bc =>
72+ val pre1 = bc.thisType.typeSymbol.companionClass.thisType
73+ pre1.findMember(name, pre1, required, excluded)
74+ }.find(_.exists).getOrElse(NoDenotation )
75+
76+ if preSym.isClass then
77+ directSearch orElse searchCompanionClass orElse searchSuperCompanionObjects
78+ else
79+ directSearch
80+ }
81+
4582 /** A fresh local context with given tree and owner.
4683 * Owner might not exist (can happen for self valdefs), in which case
4784 * no owner is set in result context
0 commit comments