Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix extending protected nested java classes #21857

Merged
merged 3 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,14 @@ object SymbolLoaders {
*/
def enterClassAndModule(
owner: Symbol, name: PreName, completer: SymbolLoader,
flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(using Context): Unit = {
flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(using Context): (Symbol, Symbol) = {
val clazz = enterClass(owner, name, completer, flags, scope)
val module = enterModule(
owner, name, completer,
modFlags = flags.toTermFlags & RetainedModuleValFlags,
clsFlags = flags.toTypeFlags & RetainedModuleClassFlags,
scope = scope)
(clazz, module)
}

/** Enter all toplevel classes and objects in file `src` into package `owner`, provided
Expand Down
16 changes: 11 additions & 5 deletions compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,10 @@ class ClassfileParser(

val privateWithin = getPrivateWithin(jflags)

classRoot.setPrivateWithin(privateWithin)
moduleRoot.setPrivateWithin(privateWithin)
moduleRoot.sourceModule.setPrivateWithin(privateWithin)
if privateWithin.exists then
classRoot.setPrivateWithin(privateWithin)
moduleRoot.setPrivateWithin(privateWithin)
moduleRoot.sourceModule.setPrivateWithin(privateWithin)

for (i <- 0 until in.nextChar) parseMember(method = false)
for (i <- 0 until in.nextChar) parseMember(method = true)
Expand Down Expand Up @@ -1058,13 +1059,18 @@ class ClassfileParser(
*/
private def enterOwnInnerClasses()(using Context, DataReader): Unit = {
def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) =
SymbolLoaders.enterClassAndModule(
val (cls, mod) = SymbolLoaders.enterClassAndModule(
getOwner(jflags),
entry.originalName,
entry.originalName,
new ClassfileLoader(file),
classTranslation.flags(jflags),
getScope(jflags))

val privateWithin = getPrivateWithin(jflags)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if privateWithin.exists then here as well for consistency?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

cls.setPrivateWithin(privateWithin)
mod.setPrivateWithin(privateWithin)
mod.sourceModule.setPrivateWithin(privateWithin)

for entry <- innerClasses.valuesIterator do
// create a new class member for immediate inner classes
if entry.outer.name == currentClassName then
Expand Down
7 changes: 7 additions & 0 deletions compiler/src/dotty/tools/dotc/printing/Formatting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ object Formatting {
case Atoms.Range(lo, hi) => CtxShow(s"Range(${toStr(lo.toList)}, ${toStr(hi.toList)})")
end given

given Show[ast.untpd.Modifiers] with
def show(x: ast.untpd.Modifiers) =
CtxShow(s"Modifiers(${toStr(x.flags)}, ${toStr(x.privateWithin)}, ${toStr(x.annotations)}, ${toStr(x.mods)})")
dwijnand marked this conversation as resolved.
Show resolved Hide resolved

given Show[ast.untpd.Mod] with
def show(x: ast.untpd.Mod) = CtxShow(s"Mod(${toStr(x.flags)})")

given Show[Showable] = ShowAny
given Show[Shown] = ShowAny
given Show[Int] = ShowAny
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i21631_joint/AbstractChannel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public abstract class AbstractChannel {
protected AbstractChannel() {}
protected abstract AbstractUnsafe newUnsafe();
protected abstract class AbstractUnsafe {
public abstract void connect();
}
}
5 changes: 5 additions & 0 deletions tests/pos/i21631_joint/i21631.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Channel extends AbstractChannel() {
override def newUnsafe(): AbstractChannel#AbstractUnsafe = new AbstractUnsafe {
override def connect(): Unit = ???
}
}
7 changes: 7 additions & 0 deletions tests/pos/i21631_separ/AbstractChannel_1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public abstract class AbstractChannel_1 {
protected AbstractChannel_1() {}
protected abstract AbstractUnsafe newUnsafe();
protected abstract class AbstractUnsafe {
public abstract void connect();
}
}
5 changes: 5 additions & 0 deletions tests/pos/i21631_separ/i21631_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Channel extends AbstractChannel_1() {
override def newUnsafe(): AbstractChannel_1#AbstractUnsafe = new AbstractUnsafe {
override def connect(): Unit = ???
}
}
Loading