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

runtime reflection java interop: inner classes are read in a weird way #7072

Open
scabug opened this issue Feb 4, 2013 · 2 comments
Open

runtime reflection java interop: inner classes are read in a weird way #7072

scabug opened this issue Feb 4, 2013 · 2 comments

Comments

@scabug
Copy link

@scabug scabug commented Feb 4, 2013

package foo;

public class JavaClass_1 {
  private class PrivateJavaClass {}
  protected class ProtectedJavaClass {}
  public class PublicJavaClass {}
}

=====

import scala.reflect.runtime.universe._

package object foo {
  def testAll(): Unit = {
    test(typeOf[foo.JavaClass_1].typeSymbol)
  }

  def test(sym: Symbol): Unit = {
    printSymbolDetails(sym)
    if (sym.isClass || sym.isModule) {
      sym.typeSignature.declarations.toList.sortBy(_.name.toString) foreach test
    }
  }

  def printSymbolDetails(sym: Symbol): Unit = {
    def stableSignature(sym: Symbol) = sym.typeSignature match {
      case ClassInfoType(_, _, _) => "ClassInfoType(...)"
      case tpe => tpe.toString
    }
    println("============")
    println(s"sym = $sym, signature = ${stableSignature(sym)}, owner = ${sym.owner}")
    println(s"isPrivate = ${sym.isPrivate}")
    println(s"isProtected = ${sym.isProtected}")
    println(s"isPublic = ${sym.isPublic}")
    println(s"privateWithin = ${sym.privateWithin}")
  }
}

object Test extends App {
  foo.testAll()
}
============
sym = class JavaClass_1, signature = ClassInfoType(...), owner = package foo
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
sym = class $PrivateJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
sym = value this$0, signature = foo.JavaClass_1, owner = class $PrivateJavaClass
isPrivate = false
isProtected = false
isPublic = false
privateWithin = package foo
============
sym = object $PrivateJavaClass, signature = JavaClass_1.this.$PrivateJavaClass.type, owner = class JavaClass_1
isPrivate = true
isProtected = false
isPublic = false
privateWithin = <none>
============
sym = class $ProtectedJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
isPrivate = false
isProtected = true
isPublic = false
privateWithin = package foo
============
sym = value this$0, signature = foo.JavaClass_1, owner = class $ProtectedJavaClass
isPrivate = false
isProtected = false
isPublic = false
privateWithin = package foo
============
sym = object $ProtectedJavaClass, signature = JavaClass_1.this.$ProtectedJavaClass.type, owner = class JavaClass_1
isPrivate = false
isProtected = false
isPublic = false
privateWithin = package foo
============
sym = class $PublicJavaClass, signature = ClassInfoType(...), owner = class JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
sym = constructor $PublicJavaClass, signature = (x$1: foo.JavaClass_1)JavaClass_1.this.$PublicJavaClass, owner = class $PublicJavaClass
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
sym = value this$0, signature = foo.JavaClass_1, owner = class $PublicJavaClass
isPrivate = false
isProtected = false
isPublic = false
privateWithin = package foo
============
sym = object $PublicJavaClass, signature = JavaClass_1.this.$PublicJavaClass.type, owner = class JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>
============
sym = constructor JavaClass_1, signature = ()foo.JavaClass_1, owner = class JavaClass_1
isPrivate = false
isProtected = false
isPublic = true
privateWithin = <none>

Problems:

  1. Names of inner classes begin with a dollar.
  2. Inner classes get a strange this$0 value.
  3. Non-public inner classes appear to not have any constructors (possibly related to #7071).
  4. Inner classes get companion modules, even though they don't have static definitions.
@scabug
Copy link
Author

@scabug scabug commented Feb 4, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7072?orig=1
Reporter: @xeno-by
Affected Versions: 2.10.0

@retronym
Copy link
Member

@retronym retronym commented Jul 6, 2017

Just ran into this. Part of the problem lies in:

    private def scalaSimpleName(jclazz: jClass[_]): TypeName = {
      val owner = sOwner(jclazz)
      val enclosingClass = jclazz.getEnclosingClass
      var prefix = if (enclosingClass != null) enclosingClass.getName else ""
      val isObject = owner.isModuleClass && !owner.isPackageClass
      if (isObject && !prefix.endsWith(nme.MODULE_SUFFIX_STRING)) prefix += nme.MODULE_SUFFIX_STRING
      assert(jclazz.getName.startsWith(prefix))
      var name = jclazz.getName.substring(prefix.length)
      name = name.substring(name.lastIndexOf(".") + 1)
      newTypeName(name)
    }

which fails to remove the $ from Outer$Inner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants