This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Working with scala.tools.nsc.interactive

2 replies
Roman Roelofsen
Joined: 2009-03-03,
User offline. Last seen 42 years 45 weeks ago.

Hi,

I am trying to use the scala.tools.nsc.interactive package to provide
code completion within the Vim editor. I saw Aemon's impressive Emacs
plugin/screencast and simply want to provide the same features for Vim.

By walking through the nsc and ensime sourcecode I was able to set up a
basic proof of concept (member completion). However, I get an exception
when I repeatedly call into the interactive compiler and I have an issue
that I could only solve with a stupid Thread.sleep for now. I assume
that I am not using the compiler correctly.

To get a member completion I basically do this:

1) Create settings object, etc.
val settings = new Settings(Console.println)
settings.processArguments(compilerArgs, true)

2) Create interactive compiler
compiler = new scala.tools.nsc.interactive.Global(settings, ...)
compiler.newRunnerThread

3) Load all source files
val x = new Response[Unit]
compiler.askReload(, x)
x.get

4) Member completion
val x = new Response[List[Member]]
val p = new OffsetPosition(getSourceFile(file), cursor)
askTypeCompletion(p, x)
// check x etc.

Problem 1
----------------
Step 4 successfully returns a list of members. However, I can not
re-execute step 4. I always need to reload the file (step 3) first. Is
this behavior intended or am I doing it wrong?

Problem 2
-----------------
I had to put a Thread.sleep between the reloading of the files (step 3)
and the member completion (step 4). Without it I *sometimes* get
exceptions like "illegal cyclic inheritance" and "constructor XXX is
defined twice". Sometimes its working, sometimes not. I thought that
x.get in step 3 ensures that the reloading finished but its seems that
some work still needs to finish before I can do step 4.

Does anyone know how to solve this?

Cheers,

Roman

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Working with scala.tools.nsc.interactive

On Sun, Jun 20, 2010 at 03:41:23PM +0200, Roman Roelofsen wrote:
> I had to put a Thread.sleep between the reloading of the files (step
> 3) and the member completion (step 4). Without it I *sometimes* get
> exceptions like "illegal cyclic inheritance" and "constructor XXX is
> defined twice". Sometimes its working, sometimes not.

I am overly familiar with this phenomenon in a slightly different
context (the repl) where I don't use the interactive.* classes but I do
have to deal with multiple threads wanting to squeeze some facts out of
a Global. And having seen all those same messages in the same
non-deterministic fashion, and also having sometimes resorted to
measures like calling Thread.`yield`, I didn't really eliminate them
until I religiously routed all attempts to call methods on the global
through a sequential access choke point. (That code isn't checked in,
it's in my repl rewrite.)

That doesn't tell you much about what you're supposed to do with the
interactive.Global, which I assume has dealt with this problem robustly
since it is designed to be run in a multithreaded scenario, and the repl
originally wasn't. But at least you know you're not alone.

Roman Roelofsen
Joined: 2009-03-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Working with scala.tools.nsc.interactive

On 06/20/2010 05:42 PM, Paul Phillips wrote:
> That doesn't tell you much about what you're supposed to do with the
> interactive.Global, which I assume has dealt with this problem robustly
> since it is designed to be run in a multithreaded scenario, and the repl
> originally wasn't. But at least you know you're not alone.
>
Good to know :-) Debugging timing things is annoying :-/

Anyway, I think I solved my problem! Not sure if it will help you since
you are not using the interactive stuff.

The trick is to wait until the Global.recompile method was executed.

Cheers,

Roman

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland