bug icon indicating copy to clipboard operation
bug copied to clipboard

name mangling vs. java reflection

Open scabug opened this issue 14 years ago • 9 comments

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

scabug avatar Mar 06 '11 10:03 scabug