bug
bug copied to clipboard
name mangling vs. java reflection
As of r24390 signatures appear to be in good shape with the exception of this, which I can only document for now. Actually this is not about signatures per se, but names which cause java -Xprint to fail.
class Bippy {
val quuxVal = () => new AnyRef // fails
lazy val quuxLazy = () => new AnyRef // works
def quuxDef = () => new AnyRef // works
}
// Only val excludes the name.
//
// -rw-r--r-- 1 paulp staff 614 Mar 6 12:37 Bippy$$anonfun$1.class
// -rw-r--r-- 1 paulp staff 667 Mar 6 12:37 Bippy$$anonfun$quuxDef$1.class
// -rw-r--r-- 1 paulp staff 670 Mar 6 12:37 Bippy$$anonfun$quuxLazy$1.class
// -rw-r--r-- 1 paulp staff 1340 Mar 6 12:37 Bippy.class
//
// Only val turns up in getClasses, and not anonymously.
//
// % scala -nocompdaemon -e 'classOf[Bippy].getClasses foreach println'
// class Bippy$$anonfun$1
// % scala -nocompdaemon -e 'classOf[Bippy].getClasses map (_.isAnonymousClass) foreach println'
// false
//
// Only val has a symmetric inner class relationship.
//
// Bippy-side:
// InnerClass:
// public final SI-44 of SI-14; //class Bippy$$anonfun$1 of class Bippy
// public final SI-36; //class Bippy$$anonfun$quuxDef$1
// public final SI-21; //class Bippy$$anonfun$quuxLazy$1
//
// Closure-side:
// % for file in Bippy\$*.class ; do javap -verbose "${file%.class}" | grep '//class Bippy' ; done
// public final SI-9 of SI-32; //class Bippy$$anonfun$1 of class Bippy
// public final SI-9; //class Bippy$$anonfun$quuxDef$1
// public final SI-9; //class Bippy$$anonfun$quuxLazy$1
Here is the java equivalent of the failing construct:
// Bippy.java
public class Bippy {
scala.Function0<Object> quux = new scala.runtime.AbstractFunction0<Object>() {
public Object apply() {
return new Object();
}
};
}
In an unsurprising twist, java creates the inner class java is looking for:
InnerClass:
SI-2; //class Bippy$1
% javac7 -cp /scala/inst/29/lib/scala-library.jar:. -Xprint Bippy
public class Bippy {
scala.Function0<java.lang.Object> quux;
public Bippy();
}
The successful output from the lazy val and def cases:
class Bippy {
// InnerClass:
// public final SI-7; //class Bippy$$anonfun$quux$1
def quux = () => new AnyRef
}
@scala.reflect.ScalaSignature(bytes=...)
public class Bippy implements scala.ScalaObject {
public scala.Function0<java.lang.Object> quux();
public Bippy();
}
class Bippy {
// InnerClass:
// public final SI-17; //class Bippy$$anonfun$quux$1
lazy val quux = () => new AnyRef
}
@scala.reflect.ScalaSignature(bytes=...)
public class Bippy implements scala.ScalaObject {
private scala.Function0<java.lang.Object> quux;
public volatile int bitmap$0;
public scala.Function0<java.lang.Object> quux();
public Bippy();
}
The failing output from the val case:
% javac7 -cp /scala/inst/29/lib/scala-library.jar:. -Xprint Bippy
error: cannot access 1
class file for Bippy$1 not found
1 error