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
Can't get symbol for local class #6622
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6622?orig=1 |
@paulp said: |
Ryan Hendrickson (ryan.hendrickson_bwater) said: package si6622
// Pulled out to rule out any potential DelayedInit shenanigans
object NotTheRepl {
val result = {
class A
reflect.runtime.currentMirror.classSymbol((new A).getClass)
}
}
object RunMe extends App {
println(NotTheRepl.result)
} |
@paulp said: object NotTheRepl {
def f = {
class A
scala.reflect.runtime.currentMirror.classSymbol((new A).getClass)
}
}
object RunMe extends App {
println(NotTheRepl.f)
}
// % rcscala RunMe
// class A$1
// % |
Evgeny (akshaal) said (edited on Apr 30, 2013 5:33:41 PM UTC):
|
@retronym said (edited on Jun 6, 2014 7:07:00 AM UTC): I haven't quite figured out why def-vs-val is material; it may be a bug in the bytecode emitter. Test: object NotTheRepl1 {
lazy val resultVal = {
class A
println("NotTheRepl1.resultVal::A " + classOf[A].isMemberClass)
reflect.runtime.currentMirror.classSymbol((new A).getClass)
}
def resultDef = {
class A
println("NotTheRepl1.resultDef::A " + classOf[A].isMemberClass)
reflect.runtime.currentMirror.classSymbol((new A).getClass)
}
}
object NotTheRepl2 {
val resultVal = {
class B
println("NotTheRepl2.resultVal::B " + classOf[B].isMemberClass)
reflect.runtime.currentMirror.classSymbol((new B).getClass)
}
}
object NotTheRepl3 {
def resultDef = {
class C
println("NotTheRepl3.resultDef::C " + classOf[C].isMemberClass)
reflect.runtime.currentMirror.classSymbol((new C).getClass)
}
}
object Test extends App {
println(NotTheRepl3.resultDef)
println(NotTheRepl1.resultDef)
println(NotTheRepl2.resultVal)
println(NotTheRepl1.resultVal)
}
Breadcrumbs: // `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName`
// hence we have to approximate by removing the `isAnonymousClass` check
// def isLocalClass0: Boolean = jclazz.isLocalClass
def isLocalClass0: Boolean = jclazz.getEnclosingMethod != null || jclazz.getEnclosingConstructor != null if (jclazz.isMemberClass) {
val jEnclosingClass = jclazz.getEnclosingClass
val sEnclosingClass = classToScala(jEnclosingClass)
followStatic(sEnclosingClass, jclazz.javaFlags)
} else if (jclazz.isLocalClass0) {
val jEnclosingMethod = jclazz.getEnclosingMethod
if (jEnclosingMethod != null) {
methodToScala(jEnclosingMethod)
} else {
val jEnclosingConstructor = jclazz.getEnclosingConstructor
constructorToScala(jEnclosingConstructor)
}
....
val cls =
if (jclazz.isMemberClass && !nme.isImplClassName(jname))
lookupClass
else if (jclazz.isLocalClass0 || isInvalidClassName(jname))
// local classes and implementation classes not preserved by unpickling - treat as Java
//
// upd. but only if they cannot be loaded as top-level classes
// otherwise we may mistake mangled symbolic names for mangled nested names
//
// in case when a Java binary name can be treated both as a top-level class and as a nested class
// (as described in http://groups.google.com/group/scala-internals/browse_thread/thread/10855403bbf04298)
// we check for a top-level class first
// this is totally correct, because a top-level class and a nested class with the same name cannot coexist
// so it's either one or another, but not both - therefore we always load $-bearing classes correctly
lookupClass orElse jclassAsScala(jclazz) /** Return the name of this symbol that can be used on the Java platform. It removes spaces from names.
*
* Special handling:
* scala.Nothing erases to scala.runtime.Nothing$
* scala.Null erases to scala.runtime.Null$
*
* This is needed because they are not real classes, and they mean
* 'abrupt termination upon evaluation of that expression' or null respectively.
* This handling is done already in GenICode, but here we need to remove
* references from method signatures to these types, because such classes
* cannot exist in the classpath: the type checker will be very confused.
*/
def javaName(sym: Symbol): String = {
/*
* Checks if given symbol corresponds to inner class/object and add it to innerClassBuffer
*
* Note: This method is called recursively thus making sure that we add complete chain
* of inner class all until root class.
*/
def collectInnerClass(s: Symbol): Unit = {
// TODO: some enteringFlatten { ... } which accounts for
// being nested in parameterized classes (if we're going to selectively flatten.)
val x = innerClassSymbolFor(s)
if(x ne NoSymbol) {
assert(x.isClass, "not an inner-class symbol")
val isInner = !x.rawowner.isPackageClass
if (isInner) {
innerClassBuffer += x
collectInnerClass(x.rawowner)
}
}
} protected def originalEnclosingMethod(sym: Symbol): Symbol = {
if (sym.isMethod || sym == NoSymbol) sym
else {
val owner = originalOwner.getOrElse(sym, sym.rawowner)
if (sym.isLocalDummy) owner.enclClass.primaryConstructor
else originalEnclosingMethod(owner)
}
}
|
@retronym said: |
@adriaanm said: |
@gkossakowski said: |
@lrytz said: |
I saw #5431 and #6323; not sure if it'd be better to reopen one of those or file this as new.
The text was updated successfully, but these errors were encountered: