10786 setting privateWithin for java protected inner classes#7323
10786 setting privateWithin for java protected inner classes#7323adriaanm merged 1 commit intoscala:2.12.xfrom
Conversation
|
Here's how I tested it locally: I see that in the scala hacker guide it mentions: "Code which should compile successfully, but doesn’t need to be executed, needs to go into the “pos” directory." Would I just place those files in pos then (minus the print statements)? |
This comment has been minimized.
This comment has been minimized.
| (newStub(name.toTypeName), newStub(name.toTermName)) | ||
| } else { | ||
| val cls = owner.newClass(name.toTypeName, NoPosition, sflags) | ||
| if (cls.isProtected) { |
There was a problem hiding this comment.
Looks like the right spot to me. The other cases seem to use propagatePackageBoundary. I'm not super familiar with this part. Assigning lrytz for review :-)
|
Welcome, @psilospore, and congrats already on your first scalac bug fix 👏 🍰 |
lrytz
left a comment
There was a problem hiding this comment.
It took me a looong while to understand what's going on here, but in the end your change seems to be the correct fix.
Here's my test case:
A.java
package a.b;
public class A {
static class N1 {
public int x = 1;
public static int y = 1;
}
static protected class N2 {
public int x = 1;
public static int y = 1;
}
}Test.sclaa
package a.b {
class C {
class T1 extends A.N1
class T2 extends A.N2
def test(): Unit = {
val n1 = new A.N1
n1.x
A.N1.y
val n2 = new A.N2
n2.x
A.N2.y
}
class I extends A {
class T1 extends A.N1
class T2 extends A.N2
def test(): Unit = {
val n1 = new A.N1
n1.x
A.N1.y
val n2 = new A.N2
n2.x
A.N2.y
}
}
}
}I was wondering why the bug only affects N2, but not N1. What's going on:
- The classfile parser for
Acreates symbols for all nested classes (enterOwnInnerClasses) - When those inner symbols complete, the classfile parser runs on
A$N1/A$N2etc- There is an invocation of
propagatePackageBoundary, which sets theprivateWithinforN1, because the classfileA$N1has no access modifier - However, this does not happen for
A$N2, because that classfile is markedpublicin bytecode (!). The JVM access rules require making the class public (this will probably change on Java 11 with nestmates?)
- There is an invocation of
Could you
- Add a comment to your fix? Something like "need to set
privateWithinhere because the classfile of a nested protected class is public in bytecode, sopropagatePackageBoundarywill not set it when the symbols are completed" - Extend the test case to test access to a static member within the nested class
src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
Outdated
Show resolved
Hide resolved
lrytz
left a comment
There was a problem hiding this comment.
Great, thank you! This looks good now. Could you squash all commits into a single one and write a summary for the commit message?
modules loaded by classpath, and created tests.
|
Thanks, @psilospore! |
|
congrats on your first PR, @psilospore! |
First PR to scala hopefully it's right. This fixes scala/bug#10786