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
Milestone

Comments

@scabug
Copy link

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 runtime reflection java interop: non-public constructors aren't present in declarations #7071).
  4. Inner classes get companion modules, even though they don't have static definitions.
@scabug
Copy link
Author

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 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

@SethTisue SethTisue added this to the Backlog milestone Mar 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants