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

Parameter name changed after compilation #6028

Closed
scabug opened this issue Jul 5, 2012 · 11 comments
Closed

Parameter name changed after compilation #6028

scabug opened this issue Jul 5, 2012 · 11 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jul 5, 2012

I use spring mvc to create the controllers.
Every thing is ok, but some parameters have been rename after compile in somes method of my controllers.

I found that in debug mode of idea

// TravelSheetController.scala
@RequestMapping(value = Array(""), method = Array(RequestMethod.GET))
@ResponseBody
def query(
        @RequestParam(value="start", defaultValue="0") start:Int,
        @RequestParam(value="limit", defaultValue="10") limit:Int,
        @RequestParam(required = false) startDate: String,
        @RequestParam(required = false) endDate: String,
        @RequestParam(defaultValue="0") driverId: Long): PaginationBase[TravelSheetDto] = {
       // ignore code
}

the driverId is rename to driverId$1, So I cannot receive the value from spring mvc.

Here's a minimal reproduction by Jason Zaugg:

scala> class T { def foo(a: Int) = () => a }
defined class T

scala> :javap -v T
Compiled from "<console>"
...
public scala.Function0 foo(int);
  Code:
   Stack=4, Locals=2, Args_size=2
   0:   new     #7; //class T$$anonfun$foo$1
   3:   dup
   4:   aload_0
   5:   iload_1
   6:   invokespecial   #12; //Method T$$anonfun$foo$1."<init>":(LT;I)V
   9:   areturn
  LineNumberTable:
   line 7: 0

  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      10      0    this       LT;
   0      10      1    a$1       I
@scabug
Copy link
Author

scabug commented Jul 5, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6028?orig=1
Reporter: wang (wangyb7)
Affected Versions: 2.9.2
Other Milestones: 2.10.0

@scabug
Copy link
Author

scabug commented Jul 6, 2012

@adriaanm said:
Lukas, do you know why we mangle parameter names in the bytecode?

@scabug
Copy link
Author

scabug commented Jul 6, 2012

@paulp said:
It's a bug. It happens during lambdalift, and it tries to avoid it. Look at the eerie similarity of the example in the comment.

beforePickler {
  // The param symbol in the MethodType should not be renamed, only the symbol in scope. This way,
  // parameter names for named arguments are not changed. Example: without cloning the MethodType,
  //     def closure(x: Int) = { () => x }
  // would have the signature
  //     closure: (x$1: Int)() => Int
  if (sym.isParameter && sym.owner.info.paramss.exists(_ contains sym))
    sym.owner modifyInfo (_ cloneInfo sym.owner)
}

@scabug
Copy link
Author

scabug commented Jul 6, 2012

@retronym said (edited on Jul 6, 2012 10:20:10 PM UTC):
That does just enough to retain the unmangled name in the pickled signatures, which is needed for named args.

@scabug
Copy link
Author

scabug commented Jul 7, 2012

@retronym said:
https://github.com/retronym/scala/compare/ticket/6028

SI-6028 Restore original parameter names after lambdalift

Extends what was being done only in the pickled signatures to
the bytecode proper. Once the code has been lifted out of a tree,
we can undo the mangling in that tree.

This only does this for parameter name, but I suspect it could and
should be done for all symbols, which will present a few less mangled
 names in the debugger.

Do we have any test infrastructure for verifying this? Can we compare
-Xprint:lambdalift against a checkfile?

@scabug
Copy link
Author

scabug commented Jul 7, 2012

@retronym said:
I went further and restored the names of all symbols captured by lifted free variables.

ticket/6028 ~/code/scala cat test/files/pos/t6028.scala 
class T {
  def foo(a: Int) = {val b = 0 ; () => a + b }
}
ticket/6028 ~/code/scala diff -u pre-6028.txt post-6028.txt 
--- pre-6028.txt	2012-07-07 11:49:06.000000000 +0200
+++ post-6028.txt	2012-07-07 11:47:53.000000000 +0200
@@ -1,14 +1,14 @@
-[[syntax trees at end of lambdalift]]// Scala source: t6028.scala
+[[syntax trees at end of                lambdalift]] // t6028.scala
 package <empty> {
   class T extends Object {
     def <init>(): T = {
       T.super.<init>();
       ()
     };
-    def foo(a$1: Int): Function0 = {
-      val b$1: Int = 0;
+    def foo(a: Int): Function0 = {
+      val b: Int = 0;
       {
-        (new anonymous class $anonfun$foo$1(T.this, a$1, b$1): Function0)
+        (new anonymous class $anonfun$foo$1(T.this, a, b): Function0)
       }
     };
     @SerialVersionUID(0) final <synthetic> class $anonfun$foo$1 extends scala.runtime.AbstractFunction0$mcI$sp with Serializable {
@@ -25,5 +25,4 @@
       <synthetic> <paramaccessor> private[this] val b$1: Int = _
     }
   }
-}
-
+}

@scabug
Copy link
Author

scabug commented Jul 7, 2012

@retronym said:
scala/scala#847

@scabug
Copy link
Author

scabug commented Jul 7, 2012

@paulp said:
"I went further and restored the names of all symbols captured by lifted free variables."

Awesome!

@scabug
Copy link
Author

scabug commented Jul 10, 2012

@retronym said:
Bumping to critical so it's considered for 2.10.

@scabug
Copy link
Author

scabug commented Jul 17, 2012

@retronym said:
Merged in scala/scala@d9629db638

@scabug scabug closed this as completed Jul 17, 2012
@scabug
Copy link
Author

scabug commented Oct 23, 2012

@retronym said:
BTW, a workaround is to use @RequestParam("paramName") to explicitly bind the parameter to a name.

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

2 participants