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

valueOfTerm method of scala.tools.nsc.interpreter.IMain broken in 2.9.1 RC2 #4899

Closed
scabug opened this issue Aug 11, 2011 · 10 comments
Closed
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Aug 11, 2011

The valueOfTerm method of scala.tools.nsc.interpreter.IMain seems to be broken in 2.9.1 RC2, whereas it works as expected in 2.9.0.1. See transcripts from both versions below.

      - 2.9.1.RC2 ##############

Welcome to Scala version 2.9.1.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val n = new scala.tools.nsc.interpreter.IMain()
n: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@f4f7a86

scala> n.interpret("val a = 2+3")
a: Int = 5
res0: scala.tools.nsc.interpreter.package.IR.Result = Success

scala> n.valueOfTerm("a") == Some(5) // Should be true!
res1: Boolean = false

      - 2.9.0.1 ##############

Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val n = new scala.tools.nsc.interpreter.IMain()
n: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@34ae19a

scala> n.interpret("val a = 2+3")
a: Int = 5
res0: scala.tools.nsc.interpreter.Results.Result = Success

scala> n.valueOfTerm("a") == Some(5) // Is true, as it should be
res1: Boolean = true

@scabug
Copy link
Author

scabug commented Aug 11, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4899?orig=1
Reporter: David B. Dahl (dahl)
Affected Versions: 2.9.1

@scabug
Copy link
Author

scabug commented Sep 11, 2011

Eugene Yokota (eed3si9n) said:
I'm still seeing this with 2.9.1.final. Why is the Fix Version/s set to Scala 2.9.0-1?

@scabug
Copy link
Author

scabug commented Oct 1, 2011

Sebastien Riou (acapola) said:
Similar thing here, with 2.9.1.final:
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Server VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val n = new scala.tools.nsc.interpreter.IMain()
n: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@5c18ff

scala> n.interpret("val r=1")
r: Int = 1
res0: scala.tools.nsc.interpreter.package.IR.Result = Success

scala> n.valueOfTerm("r")
res1: Option[AnyRef] = None

How to get the value of r then ???

@scabug
Copy link
Author

scabug commented Oct 10, 2011

Zach Cox (zcox) said:
I see this too with 2.9.1.final:

Welcome to Scala version 2.9.1.final (OpenJDK 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val n = new scala.tools.nsc.interpreter.IMain()
n: scala.tools.nsc.interpreter.IMain = scala.tools.nsc.interpreter.IMain@3f6a5d72

scala>  n.interpret("val r=1")
r: Int = 1
res0: scala.tools.nsc.interpreter.package.IR.Result = Success

scala> n.valueOfTerm("r")
res1: Option[AnyRef] = None

The underlying cause of this is that ReadEvalPrint.call throws an exception if you try to access the evaluated value:

Welcome to Scala version 2.9.1.final (OpenJDK 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.tools.nsc.interpreter._
import scala.tools.nsc.interpreter._

scala> class MyIMain extends IMain {
     | def lastRequest = prevRequestList.last
     | }
defined class MyIMain

scala> val n = new MyIMain()
n: MyIMain = MyIMain@1483ce25

scala> n.interpret("val a = 1")
import scala.tools.nsc.interpreter._
res0: scala.tools.nsc.interpreter.package.IR.Result = Success

scala> val r = n.lastRequest
r: n.Request = Request(line=val a = 1, 1 trees)

scala> r.lineRep.call(r.lineRep.evalName)
java.lang.RuntimeException: Internal error: eval object class $line1.$eval, 

	at scala.sys.package$.error(package.scala:27)
	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.evalMethod(IMain.scala:750)
	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
	at .<init>(<console>:14)
	at .<clinit>(<console>)
	at .<init>(<console>:11)
	at .<clinit>(<console>)
	at $print(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:616)
	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
	at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
	at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
	at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
	at java.lang.Thread.run(Thread.java:636)

IMain.valueOfTerm ultimately calls ReadEvalPrint.callEither which swallows that exception and eventually a None bubbles up and gets returned. I haven't done any more digging as to why that exception is thrown, will report more details if I find them.

Are there any known workarounds for this? We're embedding the Scala REPL and trying to customize the Print stage to dump the contents of any eval'ed collection or iterator in Gremlin and this bug is impeding progress.

@scabug
Copy link
Author

scabug commented Oct 11, 2011

Sebastien Riou (acapola) said:
In my case, I reverted to 2.9.0.1 to get things going...

@scabug
Copy link
Author

scabug commented Oct 17, 2011

Wiktor Macura (wmacura) said (edited on Oct 17, 2011 7:27:07 PM UTC):
Hi!

It seems that the problem is that r.lineRep.evalName returns $eval. If we call r.lineRep.call("$result") directly we get the results as expected:

object IMainSpecs extends Specification {
  "IMain" should {
    "give term value" in {
      System.setProperty("settings.usejavacp.value", "true")
      val settings = new Settings()
      settings.embeddedDefaults[UXPad]
      settings.processArgumentString("-usejavacp")

      class MyIMain extends IMain(settings) {
        def lastRequest = prevRequestList.last
      }

      val n = new MyIMain()
      n.interpret("val a = 1")

      val r = n.lastRequest
      r.lineRep.call("$result").must_== (1)
    }
  }
}

@scabug
Copy link
Author

scabug commented Oct 18, 2011

Zach Cox (zcox) said:
Wiktor - are you using Scala 2.9.1? What exactly is UXPad?

If I run your code (excluding the UXPad line) in the REPL I end up with null instead of 1:

scala> r.lineRep.call("$result")
res4: AnyRef = null

If I run your Specification using sbt test then I get this exception on the n.interpret() line:

Exception in thread "Thread-10" java.lang.Error: typeConstructor inapplicable for <none>
	at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:34)
	at scala.tools.nsc.symtab.Symbols$Symbol.typeConstructor(Symbols.scala:877)
	at scala.tools.nsc.symtab.Definitions$definitions$.scala$tools$nsc$symtab$Definitions$definitions$$booltype(Definitions.scala:157)
	at scala.tools.nsc.symtab.Definitions$definitions$.init(Definitions.scala:814)
	at scala.tools.nsc.Global$Run.<init>(Global.scala:697)
	at scala.tools.nsc.interpreter.IMain.scala$tools$nsc$interpreter$IMain$$_initialize(IMain.scala:114)
	at scala.tools.nsc.interpreter.IMain$$anonfun$initialize$1.apply$mcZ$sp(IMain.scala:127)
	at scala.tools.nsc.interpreter.IMain$$anonfun$initialize$2.apply(IMain.scala:126)
	at scala.tools.nsc.interpreter.IMain$$anonfun$initialize$2.apply(IMain.scala:126)
	at scala.concurrent.ThreadRunner$$anon$2$$anonfun$run$2.apply(ThreadRunner.scala:45)
	at scala.concurrent.ThreadRunner.scala$concurrent$ThreadRunner$$tryCatch(ThreadRunner.scala:31)
	at scala.concurrent.ThreadRunner$$anon$2.run(ThreadRunner.scala:45)
	at java.lang.Thread.run(Thread.java:636)

Could you please provide more details about the environment in which that test passes for you?

@scabug
Copy link
Author

scabug commented Oct 18, 2011

Wiktor Macura (wmacura) said (edited on Oct 18, 2011 3:08:17 AM UTC):
((I finally found the preview button; my apologies.))

Yes, sorry. I should have extracted the minimal test case:

import tools.nsc.interpreter.IMain
import tools.nsc.Settings

val settings = new Settings()

class MyIMain extends IMain() {
  def lastRequest = prevRequestList.last
}

val n = new MyIMain()
n.interpret("val a = 123")

val r = n.lastRequest
println(r.lineRep.call("$result"))

Running:

[wiktor@wiktorair1 Documents]# scala -version
Scala code runner version 2.9.1.final -- Copyright 2002-2011, LAMP/EPFL

[wiktor@wiktorair1 Documents]# scala Test.scala 
a: Int = 123
123

This is on OS X, if it matters.

@scabug
Copy link
Author

scabug commented Oct 18, 2011

Zach Cox (zcox) said:
Thanks Wiktor! I did get that to work in a standalone source file (but not on the REPL - maybe some problem using an interpreter inside an interpreter...). And I'm on Ubuntu.

I made it even a bit more minimal:

class MyIMain extends tools.nsc.interpreter.IMain {
  def lastRequest = prevRequestList.last
}

val n = new MyIMain()
n.interpret("val a = 123")

println(n.lastRequest.lineRep.call("$result"))

@scabug
Copy link
Author

scabug commented Oct 18, 2011

Commit Message Bot (anonymous) said:
(extempore in r25848) Fixing valueOfTerm in the repl.

Impressed at the amount of ticket traffic for an unadvertised internal
method. All the more reason to work toward that support repl API.
Don't worry, it'll come. Closes #4899, no review.

@scabug scabug closed this as completed Oct 18, 2011
@scabug scabug added the repl label Apr 7, 2017
@scabug scabug added this to the 2.9.0-1 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants