Scala Programming Language
  1. Scala Programming Language
  2. SI-6179

cm.reflect(object) doesn't properly work for value classes

    Details

      Description

      import scala.reflect.runtime.universe._
      import scala.reflect.runtime.{currentMirror => cm}
      
      object Test extends App {
        val plus = typeOf[Int].declaration(newTermName("$plus")).asTerm.alternatives(0).asMethod
        println(cm.reflect(2).reflectMethod(plus))
      }
      
      scala.ScalaReflectionException: expected a member of class Integer, you provided method scala.Int.$plus
              at scala.reflect.runtime.JavaMirrors$JavaMirror.ErrorNotMember(JavaMirrors.scala:127)
              at scala.reflect.runtime.JavaMirrors$JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$checkMemberOf(JavaMirrors.scala:157)
              at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(JavaMirrors.scala:178)
              at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaInstanceMirror.reflectMethod(JavaMirrors.scala:159)
              at Test$delayedInit$body.apply(reflection-magicsymbols-invoke.scala:6)
              at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
              at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
              at scala.App$$anonfun$main$1.apply(App.scala:61)
              at scala.App$$anonfun$main$1.apply(App.scala:61)
              at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
              at scala.collection.immutable.List.foreach(List.scala:78)
              at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
              at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
              at scala.App$class.main(App.scala:61)
              at Test$.main(reflection-magicsymbols-invoke.scala:4)
              at Test.main(reflection-magicsymbols-invoke.scala)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
              at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
              at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
              at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
              at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
              at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
              at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
              at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
              at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
              at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:70)
              at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:92)
              at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
              at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      

        Activity

        Hide
        Paul Phillips added a comment -

        I was hoping you would already know. Someone should surely have pointed in this direction by now.

        See BoxesRunTime.java for the implementations, generated from Cleanup.scala.

        Show
        Paul Phillips added a comment - I was hoping you would already know. Someone should surely have pointed in this direction by now. See BoxesRunTime.java for the implementations, generated from Cleanup.scala.
        Hide
        Eugene Burmako added a comment -

        Wow that's super cool! Now I might actually implement this in 2.10.0.

        Show
        Eugene Burmako added a comment - Wow that's super cool! Now I might actually implement this in 2.10.0.
        Hide
        Eugene Burmako added a comment -

        Promoting to critical, because there seems to be an easy fix.

        Show
        Eugene Burmako added a comment - Promoting to critical, because there seems to be an easy fix.
        Hide
        Paul Phillips added a comment -

        Don't miss these methods in StdNames which I wrote just in case someone came along someday who wanted to do this.

            def primitiveInfixMethodName(name: Name): TermName = name match {
              case OR   => takeOr
              case XOR  => takeXor
              case AND  => takeAnd
              case EQ   => testEqual
              case NE   => testNotEqual
              case ADD  => add
              case SUB  => subtract
              case MUL  => multiply
              case DIV  => divide
              case MOD  => takeModulo
              case LSL  => shiftSignedLeft
              case LSR  => shiftLogicalRight
              case ASR  => shiftSignedRight
              case LT   => testLessThan
              case LE   => testLessOrEqualThan
              case GE   => testGreaterOrEqualThan
              case GT   => testGreaterThan
              case ZOR  => takeConditionalOr
              case ZAND => takeConditionalAnd
              case _    => NO_NAME
            }
            /** Postfix/prefix, really.
             */
            def primitivePostfixMethodName(name: Name): TermName = name match {
              case UNARY_!    => takeNot
              case UNARY_+    => positive
              case UNARY_-    => negate
              case UNARY_~    => complement
              case `toByte`   => toByte
              case `toShort`  => toShort
              case `toChar`   => toCharacter
              case `toInt`    => toInteger
              case `toLong`   => toLong
              case `toFloat`  => toFloat
              case `toDouble` => toDouble
              case _          => NO_NAME
            }
        
        Show
        Paul Phillips added a comment - Don't miss these methods in StdNames which I wrote just in case someone came along someday who wanted to do this. def primitiveInfixMethodName(name: Name): TermName = name match { case OR => takeOr case XOR => takeXor case AND => takeAnd case EQ => testEqual case NE => testNotEqual case ADD => add case SUB => subtract case MUL => multiply case DIV => divide case MOD => takeModulo case LSL => shiftSignedLeft case LSR => shiftLogicalRight case ASR => shiftSignedRight case LT => testLessThan case LE => testLessOrEqualThan case GE => testGreaterOrEqualThan case GT => testGreaterThan case ZOR => takeConditionalOr case ZAND => takeConditionalAnd case _ => NO_NAME } /** Postfix/prefix, really. */ def primitivePostfixMethodName(name: Name): TermName = name match { case UNARY_! => takeNot case UNARY_+ => positive case UNARY_- => negate case UNARY_~ => complement case `toByte` => toByte case `toShort` => toShort case `toChar` => toCharacter case `toInt` => toInteger case `toLong` => toLong case `toFloat` => toFloat case `toDouble` => toDouble case _ => NO_NAME }
        Show
        Eugene Burmako added a comment - https://github.com/scala/scala/commit/3aa221e28c3ae0381b876448e3174f0c527e9abc

          People

          • Assignee:
            Eugene Burmako
            Reporter:
            Eugene Burmako
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development