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
getDeclaredClasses seems to miss some (REPL) or all (scalac) classes (objects) declared #4023
Comments
Imported From: https://issues.scala-lang.org/browse/SI-4023?orig=1 |
@dragos said: |
@soc said: Wouldn't it be possible to do something comparable to the "static forwarders" which Scala generates in some cases? I'm working on an Enum trait and I can't think of any way how it could possibly work without getting this information from reflection. Or can you think of any workaround on how to see which objects are defined in an object? Thanks! |
@dragos said: class B {
val valuesTry1 = this.getClass.getDeclaredClasses
} Maybe even |
@soc said: object B {
class B1
private class B2
object B3
private object B4
object B5 extends B1
private object B6 extends B2
val valuesTry1 = this.getClass.getDeclaredClasses
val valuesTry2 = B.getClass.getDeclaredClasses
val valuesTry3 = getClass.getDeclaredClasses
def main(args: Array[String]) {
println("Try 1: (" + valuesTry1.length + " classes)")
valuesTry1.foreach(println)
println("Try 2: (" + valuesTry2.length + " classes)")
valuesTry2.foreach(println)
println("Try 3: (" + valuesTry3.length + " classes)")
valuesTry3.foreach(println)
val b = new B
println("Try 4: (" + b.valuesTry4.length + " classes)")
b.valuesTry4.foreach(println)
println("Try 5: (" + b.valuesTry5.length + " classes)")
b.valuesTry5.foreach(println)
println("Try 6: (" + b.valuesTry6.length + " classes)")
b.valuesTry6.foreach(println)
println("Try 7: (" + b.valuesTry7.length + " classes)")
b.valuesTry7.foreach(println)
}
}
class B {
val valuesTry4 = this.getClass.getDeclaredClasses
val valuesTry5 = B.getClass.getDeclaredClasses
val valuesTry6 = getClass.getDeclaredClasses
val valuesTry7 = classOf[B].getDeclaredClasses
} scala B
Try 1: (0 classes)
Try 2: (0 classes)
Try 3: (0 classes)
Try 4: (2 classes)
class B$$B1
class B$$B2
Try 5: (0 classes)
Try 6: (2 classes)
class B$$B1
class B$$B2
Try 7: (2 classes)
class B$$B1
class B$$B2 I really wonder what the difference between B.getClass and classOf[B] is though ... |
@dragos said: About the different ways to get a
|
@gkossakowski said: Could you check latest nightly? It contains some changes related to inner objects. |
@paulp said: |
@soc said: scala> B.main(null)
Try 1: (6 classes)
class $line1.$read$$iw$$iw$B$B1
class $line1.$read$$iw$$iw$B$B2
class $line1.$read$$iw$$iw$B$B3$
class $line1.$read$$iw$$iw$B$B4$
class $line1.$read$$iw$$iw$B$B5$
class $line1.$read$$iw$$iw$B$B6$
Try 2: (6 classes)
class $line1.$read$$iw$$iw$B$B1
class $line1.$read$$iw$$iw$B$B2
class $line1.$read$$iw$$iw$B$B3$
class $line1.$read$$iw$$iw$B$B4$
class $line1.$read$$iw$$iw$B$B5$
class $line1.$read$$iw$$iw$B$B6$
Try 3: (6 classes)
class $line1.$read$$iw$$iw$B$B1
class $line1.$read$$iw$$iw$B$B2
class $line1.$read$$iw$$iw$B$B3$
class $line1.$read$$iw$$iw$B$B4$
class $line1.$read$$iw$$iw$B$B5$
class $line1.$read$$iw$$iw$B$B6$ but compiling it with scalac and executing it still returns: % scala B
Try 1: (0 classes)
Try 2: (0 classes)
Try 3: (0 classes) I belive this has something to do with the additional nesting the REPL does, because if I modify the code, so that the object are in another nested object, it starts working too: object B {
object C {
class B1
private class B2
object B3
private object B4
object B5 extends B1
private object B6 extends B2
val valuesTry1 = this.getClass.getDeclaredClasses
val valuesTry2 = C.getClass.getDeclaredClasses
val valuesTry3 = getClass.getDeclaredClasses
}
def main(args: Array[String]) {
println("Try 1: (" + C.valuesTry1.length + " classes)")
C.valuesTry1.foreach(println)
println("Try 2: (" + C.valuesTry2.length + " classes)")
C.valuesTry2.foreach(println)
println("Try 3: (" + C.valuesTry3.length + " classes)")
C.valuesTry3.foreach(println)
}
} % scala B
Try 1: (6 classes)
class B$C$B1
class B$C$B2
class B$C$B3$
class B$C$B4$
class B$C$B5$
class B$C$B6$
Try 2: (6 classes)
class B$C$B1
class B$C$B2
class B$C$B3$
class B$C$B4$
class B$C$B5$
class B$C$B6$
Try 3: (6 classes)
class B$C$B1
class B$C$B2
class B$C$B3$
class B$C$B4$
class B$C$B5$
class B$C$B6$ It feels like we are really close to a solution to this ... |
@gkossakowski said: Thanks for testing this. This is expected in the light of how we encode inner classes inside of top-level objects. See commit message for my change for details: https://codereview.scala-lang.org/fisheye/changelog/scala-svn?cs=25639 I tried hard to make encoding regular and not introduce special case for top-level objects but found it impossible if we want both Sun's javac compiler and Eclipse compiler happy. There's an easy work-around for top-level objects: object B {
class B1
private class B2
object B3
private object B4
object B5 extends B1
private object B6 extends B2
def mirrorClassForTopLevelObject(x: Class[_]): Class[_] = Class.forName(x.getName stripSuffix "$")
val valuesTry1 = mirrorClassForTopLevelObject(this.getClass).getDeclaredClasses
val valuesTry2 = mirrorClassForTopLevelObject(B.getClass).getDeclaredClasses
val valuesTry3 = mirrorClassForTopLevelObject(getClass).getDeclaredClasses
def main(args: Array[String]) {
println("Try 1: (" + valuesTry1.length + " classes)")
valuesTry1.foreach(println)
println("Try 2: (" + valuesTry2.length + " classes)")
valuesTry2.foreach(println)
println("Try 3: (" + valuesTry3.length + " classes)")
valuesTry3.foreach(println)
}
} this code prints: Try 1: (6 classes)
class B$B1
class B$B2
class B$B3$
class B$B4$
class B$B5$
class B$B6$
Try 2: (6 classes)
class B$B1
class B$B2
class B$B3$
class B$B4$
class B$B5$
class B$B6$
Try 3: (6 classes)
class B$B1
class B$B2
class B$B3$
class B$B4$
class B$B5$
class B$B6$ How do you feel about it? At the end of the day, all those problems will disappear once we get native Scala reflection which is in the works. |
@paulp said: |
@gkossakowski said: |
@paulp said: As it stands, the same source will compile if you compile against bytecode (since the class will have been generated) but not if you compile with pure source. That's no good. |
@gkossakowski said: |
@paulp said: Think we need martin to opine here. |
@gkossakowski said: Anyway, feel free to add it to the meeting list (I don't know how to do it). |
@gkossakowski said: http://stackoverflow.com/questions/6167326/java-class-name-containing-dollar-sign |
@paulp said: |
@gkossakowski said: Personally, I'd vote for closing this issue. |
@xeno-by said (edited on Jul 11, 2012 11:23:18 AM UTC): |
@gkossakowski said: |
@xeno-by said: |
@gkossakowski said: |
@xeno-by said: |
@xeno-by said: |
@dragos said: |
@gkossakowski said: |
@xeno-by said: |
@xeno-by said: |
@gkossakowski said: object A {
object B {
class C
}
}
object Test {
def main(args: Array[String]) {
val c = Class.forName(classOf[A.B.C].getName)
println(c)
}
} prints class A$B$C I would have suggested that before if I understood your reasoning. That's exactly why we ask for more information here and there ;-) |
@gkossakowski said: |
@soc said: |
@soc said: |
This Java code works:
But this Scala code doesn't:
In fact the result depends on how you run the file.
If the file is compiled it prints:
If the code is run on the REPL I get at least classes B1 and B2, but the rest is still missing:
In my opinion it should be investigated why Java reflection doesn't work as it is supposed to be.
Considering that the object declaration does also create a class (/class file), it should also show up in getDeclaredClasses.
The text was updated successfully, but these errors were encountered: