> From: Nascif Abousalh-Neto [mailto:[EMAIL PROTECTED]] > Sent: Monday, December 09, 2002 11:46 AM > To: Nick Sieger; Galen Boyer; [EMAIL PROTECTED] > Cc: Graham Bennett > Subject: Java -> elisp communication (was RE: BanInfo wizard anyone?) > > > Hi Nick, > > > > Well, I didn't, but the beanshell is still directly involved. > > Elisp sends strings to the beanshell which invokes java > > code, and java code invokes interfaces which, through a > > proxy, print lisp forms back to stdout and are evaluated by > > `bsh-eval-r'. > > I looked into this problem some time ago, and actually got a > working interface between Transmogrify and Emacs, using their > Hook interface. You can download it from > http://home.nc.rr.com/nascifandelaine/emacs.html. > Some comments though: > 1) Development in Transmogrify has not being very active for > quite some time > (http://sourceforge.net/mailarchive/forum.php?thread_id=612615 > &forum_id=1015). The last major release is more than a year > and a half old and I don't see any signs of a new release soon.
That's a valid point. When I examined the three sourceforge-based java refactoring tools available (JRefactory, Transmogrify and Freefactor) I liked the way Transmogrify was designed the best (but maybe I didn't look closely enough at Freefactor yet). I've done a fair amount of work w/ parser generator tools in the past and thought it could be easily extended. But, if Freefactor is being more actively maintained, then it's possible that my efforts would be better focused there. I'll keep that in consideration. > 2) [snip] > 3) Both my implementation and Graham's use gnuclient to > implement the Java -> elisp side of the equation (elisp -> > Java using the BeanShell support in JDE). The reason being > that Java tools will need (and that is true for Transmogrify) > to make asynchronous calls to the elisp side. > I'm curious on how the JUCI would solve that problem, as I > assume the BeanShell call that starts the communication with > the Java portion would block until a response is received, so > how could the Java portion (in the same thread of execution) > submit a lisp form back for evaluation? Would you use > multiple BeanShell instances or multiple threads inside > Beanshell, one to submit the Java request and one to "listen" > to stdout for asynchronous evaluation requests? The latter approach is what I'm using. Java invocations made through JUCI come through a proxy which queues the invocation for execution on a separate thread. When the java code needs to invoke elisp, it prints an elisp form and blocks while waiting for results to be returned (through the beanshell's foreground thread). > An "real world" example from my Transmogrify Hook > implementation should make it clear. Let's say you use the > elisp interface to call the ExtractMethod refactoring on > Transmogrify. The steps would be: > 1) User marks a region in the current buffer and calls > "jde-transmogrify-extract-method"; > 2) This defun calls jde-eval, using the BeanShell to activate > the Transmogrify engine; > 3) Transmogrify gathers the necessary information by making > calls to the Hook interface: > Here I'm guessing a little, I don't remember exactly the > number and order of calls to the Hook interface. > For simplicity let's assume all the source code info can be > obtained in 3.2 call. It could actually require three to four > calls to obtain line number, caret position, etc. > 3.1) getUserInput (to obtain the new method name) > 3.2) getSelecteText (to obtain the body of the extracted method) > 3.3) displayMessage or displayException (for the result) > Each one of the 3.* calls will create an elisp form that will > be sent (via gnuclient) back to Emacs for evaluation. > The processing keeps going back and forth between the > Transmogrify engine and Emacs (through the hook > implementation and gnuclient) until Transmogrify has all the > info it needs, at which point: > 4) Transmogrify applies the refactoring to the source code; > 5) Transmogrify returns the control to the original jde-eval call. > 6) jde-transmogrify-extract-method completes > (this is really asking for an UML sequence diagram :-) I agree -- I'll try to put one together with some amount of detail that would show the above scenario in JUCI. > So even though the refactoring is "put in motion" by the > jde-eval call, the control of execution is pretty much in the > hands of Transmogrify. Emacs must be ready to act as an > "evaluation server", receiving forms on demand. This is the > behavior implemented by gnuserv/gnuclient. It would be great > if you can find a way to implement this behavior using > BeanShell only. You mentioned that the Java code would print > "lisp forms back to stdout and are evaluated by > `bsh-eval-r'". Doesn't that imply that you are limited to > control flows where Emacs is driving? How can the Java proxy > "trigger" the call to bsh-eval-r, get the result of the > evaluation and recover the control of the execution flow - > for example, to move from 3.1 to 3.2 in the scenario described above? I can't say that I've tested such a scenario like the above, but I'd expect to be able to get it working otherwise JUCI wouldn't be viable. The only aspect which may be tricky is the fact that multiple lisp forms must be sent back and evalled (probably one each for getUserInput, getSelectedText and displayMessage). But each lisp form evaluated would produce a result (even nil) which would have to be sent back to the beanshell. As long as there is an alternating balance between beanshell script sent to the beanshell and elisp forms sent back to Emacs, I don't think this will be an issue. [snip] Thanks for the helpful feedback. /Nick
