Subj : wrestling a rhino down to the ground (experiences with 5R5 source) To : netscape.public.mozilla.jseng From : mda@discerning.com (Mark D. Anderson) Date : Wed Jul 30 2003 10:19 pm I've been playing with the Rhino source code (cvs, mozilla/js/rhino) a little bit this past week with an interest towards how useful it would be for some JavaScript code transformation tools, using it as a pretty printer, potentially a javadoc-like tool, etc. This is a summary of what I've confronted so far and what I did about it, when I could figure anything out. 1. org.mozilla.javascript.tools.* is no longer part of the js.jar . This is a change from 5R4_1. There appears to be no target to produce a different jar containing them (say jstools.jar). Furthermore, js/rhino/toolsrc/build.xml wants to download some swing-ex stuff before it does anything. To work around this, I figured out to do: cd js/rhino ant -Dswing-ex-available=true and make my CLASSPATH be: /Users/mda/workspaces/mozilla/js/rhino/build/rhino1_5R5pre/js.jar:/Users/mda/workspaces/mozilla/js/rhino/toolsrc (that is, just use class files directly from the toolsrc area). 2. org.mozilla.javascript.Parser is not a public class. Context.getParser is not public either. Furthermore, the public methods in Context that use Parser also compile immediately, and then throw away the parse tree. The only workaround I could see was just to edit Parser.java and make Parser public. 3. The indenting in the decompiler is hardcoded. There is an "indent" parameter, but it is only the initial top-level indent. To deal with that, I made a small edit in Parser.java: static int OFFSET = 4; // how much to indent static int SETBACK = 2; // less how much for case labels public static void setDecompileOpts(int offset, int case_setback) { OFFSET = offset; SETBACK = case_setback; } 4. The debug flags in Context.java are final. I can't believe there is really any performance benefit to this, so I edited Context.java to have: // debug flags static boolean printTrees = false; static boolean printICode = false; public static void setPrintTrees(boolean pt) {printTrees = pt;} public static void setPrintICode(boolean pi) {printICode = pi;} Note that this is particularly necessary because Node.toStringTree checks the value of Context.printTrees (rather than just doing what it is asked). 5. There appears to be no easy way to retrieve source name and line number from NativeScript. Here is my analysis of the flow, in the interpreted mode: a. make an input TokenStream from the source (this is input to Parser.parse) TokenStream has a getLineno() method b. make a Node tree (result of Parser.parse, input to Interpreter.compile) each Node knows its source name and line number c. make a NativeScript instance (result of Interpreter.compile) it does not know its source name and line number, nor know its original Node. d. make a compiled token character array (result of NativeFunction.getSourcesTree, input to Parser.decompile_r) the getSourcesTree object does not include source name and line number Here is my analysis of the flow, in the compiled mode: a. (same as interpreter mode) b. (same as interpreter mode) c. make a NativeScript instance (the result of Codegen.compile) If Context.isGeneratingSource(), then the generated java class file has appropriate pretend values for sourceName and line number. While executing, the Context.getSourcePositionFromStack hack will recover this source name and line. But the NativeScript instance itself still does not know, and does not know its Node. d. make compiled token character array (result of NativeFunction.getSourcesTree, input to Parser.decompile_r) Not even available unless Context.isGeneratingSource(), and still has no source name or line number info. I haven't decided what to do about this. One approach would be to pass in a Node tree object to Parser.java, and have it follow down the recursion. But I'll probably give up instead. (The idea here being that the pretty printer can indicate the source line of the original sources). 6. Source comments are lost from the source available for decompiling. This seems to happen in TokenStream.java, it doesn't even tokenize comments. This also undermines some desired pretty-printing abilities (or an ecmascript version of javadoc). -mda .