« Return to Thread: Rhino: JSDoc?

Re: Rhino: JSDoc?

by Marcello Bastéa-Forte :: Rate this Message:

Reply to Author | View in Thread

Apply the attached patch to rhino cvs.  (Note, this patch also has
patches for a modified version of dojo's compressor patch.)

It presently only works in interpreted mode (perhaps a good thing?), and
very simply adds a __jsdoc__ property to every function that has a /**
.. */ comment before it.  The value of the property is a string with the
leading whitespace/asterisks removed as per javadoc spec.

The inspector/doc html-generator based on this patch will be released as
part of my upcoming alt framework technical preview release
(http://marcello.cellosoft.com/projects/alt/).

Marcello


> Marcello Bastéa-Forte wrote:
>
>> If anyone is interested, I've made a patch to Rhino that records /**
>> javadoc */ tags into a __jsdoc__ property of all Function objects.
>> From there you can do whatever you like.  (I made up a script that
>> analyzes the scope to find all classes/functions and uses the jsdoc
>> information accordingly.)
>
> Wow - I'm very interested! What do I have to do?
>
>

Index: src/org/mozilla/javascript/FunctionNode.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java,v
retrieving revision 1.29
diff -u -r1.29 FunctionNode.java
--- src/org/mozilla/javascript/FunctionNode.java 29 Aug 2005 13:25:31 -0000 1.29
+++ src/org/mozilla/javascript/FunctionNode.java 26 Jul 2006 23:16:25 -0000
@@ -77,7 +77,15 @@
     public int getFunctionType() {
         return itsFunctionType;
     }
+    
+    public void setJSDoc(String s) {
+        this.jsDoc = s;
+    }
+    public String getJSDoc() {
+        return jsDoc;
+    }
 
+    String jsDoc = null;
     String functionName;
     boolean itsNeedsActivation;
     int itsFunctionType;
Index: src/org/mozilla/javascript/Interpreter.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java,v
retrieving revision 1.307
diff -u -r1.307 Interpreter.java
--- src/org/mozilla/javascript/Interpreter.java 19 Nov 2005 22:57:49 -0000 1.307
+++ src/org/mozilla/javascript/Interpreter.java 26 Jul 2006 23:16:27 -0000
@@ -487,6 +487,7 @@
         itsData.itsFunctionType = theFunction.getFunctionType();
         itsData.itsNeedsActivation = theFunction.requiresActivation();
         itsData.itsName = theFunction.getFunctionName();
+        itsData.jsDoc = theFunction.getJSDoc();
         if (!theFunction.getIgnoreDynamicScope()) {
             if (compilerEnv.isUseDynamicScope()) {
                 itsData.useDynamicScope = true;
Index: src/org/mozilla/javascript/InterpretedFunction.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/InterpretedFunction.java,v
retrieving revision 1.52
diff -u -r1.52 InterpretedFunction.java
--- src/org/mozilla/javascript/InterpretedFunction.java 28 May 2006 17:15:24 -0000 1.52
+++ src/org/mozilla/javascript/InterpretedFunction.java 26 Jul 2006 23:16:25 -0000
@@ -133,6 +133,17 @@
         if (idata.itsRegExpLiterals != null) {
             functionRegExps = createRegExpWraps(cx, scope);
         }
+        if (idata.jsDoc != null) {
+            defineProperty("__jsdoc__",
+             Context.toString(idata.getJSDoc()),
+             ScriptableObject.DONTENUM);
+            defineProperty("__source__",
+             Context.toString(idata.getSourceName()),
+             ScriptableObject.DONTENUM);
+            defineProperty("__lines__",
+             Context.javaToJS(idata.getLineNumbers(), scope),
+             ScriptableObject.DONTENUM);
+        }
     }
 
     public String getFunctionName()
Index: src/org/mozilla/javascript/TokenStream.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/TokenStream.java,v
retrieving revision 1.63
diff -u -r1.63 TokenStream.java
--- src/org/mozilla/javascript/TokenStream.java 31 Jul 2005 13:48:46 -0000 1.63
+++ src/org/mozilla/javascript/TokenStream.java 26 Jul 2006 23:16:28 -0000
@@ -284,6 +284,8 @@
     final int getLineno() { return lineno; }
 
     final String getString() { return string; }
+    
+    final String getJSDoc() { String s = jsDoc; jsDoc = null; return s; }
 
     final double getNumber() { return number; }
 
@@ -742,6 +744,11 @@
                 }
                 if (matchChar('*')) {
                     boolean lookForSlash = false;
+                    // Marcello: JSDoc patch
+                    boolean potentialJSDoc = true;
+                    boolean inJSDoc = false;
+                    boolean readJSDoc = false;
+                    int jsDocStep = 1; // 0: space, 1: star, 2: space, 3: text
                     for (;;) {
                         c = getChar();
                         if (c == EOF_CHAR) {
@@ -749,13 +756,47 @@
                             return Token.ERROR;
                         } else if (c == '*') {
                             lookForSlash = true;
+                            if (potentialJSDoc) {
+                                inJSDoc = true;
+                                potentialJSDoc = false;
+                                stringBufferTop = 0;
+                                continue;
+                            }
                         } else if (c == '/') {
                             if (lookForSlash) {
+                                if (inJSDoc)
+                                    this.jsDoc = getStringFromBuffer();
                                 continue retry;
                             }
                         } else {
                             lookForSlash = false;
                         }
+                        potentialJSDoc = false;
+                        if (inJSDoc) {
+                            // If we hit a newline restart step
+                            if (c=='\n' && jsDocStep>=1) {
+                                jsDocStep = 0;
+                                if (readJSDoc)
+                                    addToString(c);
+                                continue;
+                            } else if (jsDocStep<3) {
+                                // Ignore asterisks if we're in step 0/1
+                                if (c=='*') {
+                                    if (jsDocStep==0)
+                                        jsDocStep=1;
+                                    if (jsDocStep==1)
+                                        continue;
+                                // Ignore spaces in steps 0,1,2
+                                } else if (isJSSpace(c)) {
+                                    if (jsDocStep==1)
+                                        jsDocStep = 2;
+                                    continue;
+                                }  
+                            }
+                            jsDocStep = 3;
+                            addToString(c);
+                            readJSDoc = true;
+                        }
                     }
                 }
 
@@ -1367,6 +1408,9 @@
     // code.
     private String string = "";
     private double number;
+    
+    // Marcello: store jsdoc
+    private String jsDoc = null;
 
     private char[] stringBuffer = new char[128];
     private int stringBufferTop;
Index: src/org/mozilla/javascript/BaseFunction.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java,v
retrieving revision 1.57
diff -u -r1.57 BaseFunction.java
--- src/org/mozilla/javascript/BaseFunction.java 30 Aug 2005 10:05:42 -0000 1.57
+++ src/org/mozilla/javascript/BaseFunction.java 26 Jul 2006 23:16:25 -0000
@@ -245,6 +245,8 @@
                 } else {
                     indent = 0;
                 }
+                if (args.length>=2)
+                    flags |= ScriptRuntime.toInt32(args[1]);
             }
             return realf.decompile(indent, flags);
           }
Index: src/org/mozilla/javascript/Decompiler.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java,v
retrieving revision 1.19
diff -u -r1.19 Decompiler.java
--- src/org/mozilla/javascript/Decompiler.java 28 Aug 2005 23:25:22 -0000 1.19
+++ src/org/mozilla/javascript/Decompiler.java 26 Jul 2006 23:16:25 -0000
@@ -82,6 +82,17 @@
      * Flag to indicate that the decompilation generates toSource result.
      */
     public static final int TO_SOURCE_FLAG = 1 << 1;
+    
+    /**
+     * Flag to indicate that the decompilation generates a compressed result.
+     */
+    public static final int COMPRESS_FLAG = 1 << 2;
+
+    /**
+     * Flag to indicate that the decompilation generates a compressed result.
+     */
+    public static final int COMPRESS_NEWLINES_FLAG = 1 << 3;
+    
 
     /**
      * Decompilation property to specify initial ident value.
@@ -298,6 +309,10 @@
         StringBuffer result = new StringBuffer();
         boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
         boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+        // Compress: features
+        boolean compress = (0 != (flags & Decompiler.COMPRESS_FLAG));
+        boolean compressnl = (0 != (flags & Decompiler.COMPRESS_NEWLINES_FLAG));
+        TokenMapper tm = new TokenMapper();
 
         // Spew tokens in source, for debugging.
         // as TYPE number char
@@ -329,6 +344,10 @@
         int braceNesting = 0;
         boolean afterFirstEOL = false;
         int i = 0;
+ int prevToken = 0;
+ boolean primeFunctionNesting = false;
+ boolean inArgsList = false;
+ boolean primeInArgsList = false;
         int topFunctionType;
         if (source.charAt(i) == Token.SCRIPT) {
             ++i;
@@ -339,7 +358,9 @@
 
         if (!toSource) {
             // add an initial newline to exactly match js.
-            result.append('\n');
+            // Compress: features
+            if (!compress)
+             result.append('\n');
             for (int j = 0; j < indent; j++)
                 result.append(' ');
         } else {
@@ -349,10 +370,20 @@
         }
 
         while (i < length) {
+ // Compress: features
+ if (i>0)
+ prevToken = source.charAt(i-1);
             switch(source.charAt(i)) {
             case Token.NAME:
             case Token.REGEXP:  // re-wrapped in '/'s in parser...
-                i = printSourceString(source, i + 1, false, result);
+             // Compress:
+ int jumpPos = getSourceStringEnd(source, i+1);
+ if (!compress || Token.OBJECTLIT == source.charAt(jumpPos)) {
+ i = printSourceString(source, i + 1, false, result);
+ } else {
+ i = tm.printCompressed( source, i + 1, false, result, prevToken,
+ inArgsList, braceNesting);
+ }
                 continue;
 
             case Token.STRING:
@@ -381,7 +412,11 @@
 
             case Token.FUNCTION:
                 ++i; // skip function type
-                result.append("function ");
+ primeInArgsList = true;
+ primeFunctionNesting = true;
+                result.append("function");
+                if (Token.LP != getNext(source, length, i))
+                    result.append(' ');
                 break;
 
             case FUNCTION_END:
@@ -389,7 +424,7 @@
                 break;
 
             case Token.COMMA:
-                result.append(", ");
+                result.append(compress ? "," : ", ");
                 break;
 
             case Token.LC:
@@ -400,6 +435,7 @@
                 break;
 
             case Token.RC: {
+ tm.leaveNestingLevel(braceNesting);
                 --braceNesting;
                 /* don't print the closing RC if it closes the
                  * toplevel function and we're called from
@@ -417,18 +453,29 @@
                     case Token.WHILE:
                     case Token.ELSE:
                         indent -= indentGap;
-                        result.append(' ');
+                        if (!compress)
+                        result.append(' ');
                         break;
                 }
                 break;
             }
             case Token.LP:
+ if (primeInArgsList) {
+ inArgsList = true;
+ primeInArgsList = false;
+ }
+ if (primeFunctionNesting) {
+ tm.enterNestingLevel(braceNesting);
+ primeFunctionNesting = false;
+ }
                 result.append('(');
                 break;
 
             case Token.RP:
+ if (inArgsList)
+ inArgsList = false;
                 result.append(')');
-                if (Token.LC == getNext(source, length, i))
+                if (!compress && Token.LC == getNext(source, length, i))
                     result.append(' ');
                 break;
 
@@ -454,7 +501,7 @@
                         newLine = false;
                     }
                 }
-                if (newLine) {
+                if (newLine && !compressnl) {
                     result.append('\n');
                 }
 
@@ -482,8 +529,9 @@
                             less = indentGap;
                     }
 
-                    for (; less < indent; less++)
-                        result.append(' ');
+ if (!compress)
+    for (; less < indent; less++)
+        result.append(' ');
                 }
                 break;
             }
@@ -500,15 +548,17 @@
                 break;
 
             case Token.IF:
-                result.append("if ");
+                result.append(compress ? "if" : "if ");
                 break;
 
             case Token.ELSE:
-                result.append("else ");
+                result.append(compress ? "else" : "else ");
                 break;
 
             case Token.FOR:
-                result.append("for ");
+                result.append("for");
+                if (!compress || Token.NAME == getNext(source, length, i))
+                    result.append(' ');
                 break;
 
             case Token.IN:
@@ -516,27 +566,27 @@
                 break;
 
             case Token.WITH:
-                result.append("with ");
+                result.append(compress ? "with" : "with ");
                 break;
 
             case Token.WHILE:
-                result.append("while ");
+                result.append(compress ? "while" : "while ");
                 break;
 
             case Token.DO:
-                result.append("do ");
+                result.append(compress ? "do" : "do ");
                 break;
 
             case Token.TRY:
-                result.append("try ");
+                result.append(compress ? "try" : "try ");
                 break;
 
             case Token.CATCH:
-                result.append("catch ");
+                result.append(compress ? "catch" : "catch ");
                 break;
 
             case Token.FINALLY:
-                result.append("finally ");
+                result.append(compress ? "finally" : "finally ");
                 break;
 
             case Token.THROW:
@@ -544,7 +594,7 @@
                 break;
 
             case Token.SWITCH:
-                result.append("switch ");
+                result.append(compress ? "switch" : "switch ");
                 break;
 
             case Token.BREAK:
@@ -561,6 +611,8 @@
 
             case Token.CASE:
                 result.append("case ");
+                if (!compress || Token.NAME == getNext(source, length, i))
+                    result.append(' ');
                 break;
 
             case Token.DEFAULT:
@@ -578,63 +630,65 @@
                 break;
 
             case Token.SEMI:
-                result.append(';');
-                if (Token.EOL != getNext(source, length, i)) {
+                if (Token.EOL == getNext(source, length, i)) {
+                    if (compressnl || !compress)
+                        result.append(';');
+                } else {
                     // separators in FOR
-                    result.append(' ');
+                    result.append(compress ? ";" : "; ");
                 }
                 break;
 
             case Token.ASSIGN:
-                result.append(" = ");
+                result.append(compress ? "=" : " = ");
                 break;
 
             case Token.ASSIGN_ADD:
-                result.append(" += ");
+                result.append(compress ? "+=" : " += ");
                 break;
 
             case Token.ASSIGN_SUB:
-                result.append(" -= ");
+                result.append(compress ? "-=" : " -= ");
                 break;
 
             case Token.ASSIGN_MUL:
-                result.append(" *= ");
+                result.append(compress ? "*=" : " *= ");
                 break;
 
             case Token.ASSIGN_DIV:
-                result.append(" /= ");
+                result.append(compress ? "/=" : " /= ");
                 break;
 
             case Token.ASSIGN_MOD:
-                result.append(" %= ");
+                result.append(compress ? "%=" : " %= ");
                 break;
 
             case Token.ASSIGN_BITOR:
-                result.append(" |= ");
+                result.append(compress ? "|=" : " |= ");
                 break;
 
             case Token.ASSIGN_BITXOR:
-                result.append(" ^= ");
+                result.append(compress ? "^=" : " ^= ");
                 break;
 
             case Token.ASSIGN_BITAND:
-                result.append(" &= ");
+                result.append(compress ? "&=" : " &= ");
                 break;
 
             case Token.ASSIGN_LSH:
-                result.append(" <<= ");
+                result.append(compress ? "<<=" : " <<= ");
                 break;
 
             case Token.ASSIGN_RSH:
-                result.append(" >>= ");
+                result.append(compress ? ">>=" : " >>= ");
                 break;
 
             case Token.ASSIGN_URSH:
-                result.append(" >>>= ");
+                result.append(compress ? ">>>=" : " >>>= ");
                 break;
 
             case Token.HOOK:
-                result.append(" ? ");
+                result.append(compress ? "?" : " ? ");
                 break;
 
             case Token.OBJECTLIT:
@@ -652,59 +706,59 @@
                     result.append(':');
                 else
                     // it's the middle part of a ternary
-                    result.append(" : ");
+                    result.append(compress ? ":" : " : ");
                 break;
 
             case Token.OR:
-                result.append(" || ");
+                result.append(compress ? "||" : " || ");
                 break;
 
             case Token.AND:
-                result.append(" && ");
+                result.append(compress ? "&&" : " && ");
                 break;
 
             case Token.BITOR:
-                result.append(" | ");
+                result.append(compress ? "|" : " | ");
                 break;
 
             case Token.BITXOR:
-                result.append(" ^ ");
+                result.append(compress ? "^" : " ^ ");
                 break;
 
             case Token.BITAND:
-                result.append(" & ");
+                result.append(compress ? "&" : " & ");
                 break;
 
             case Token.SHEQ:
-                result.append(" === ");
+                result.append(compress ? "===" : " === ");
                 break;
 
             case Token.SHNE:
-                result.append(" !== ");
+                result.append(compress ? "!==" : " !== ");
                 break;
 
             case Token.EQ:
-                result.append(" == ");
+                result.append(compress ? "==" : " == ");
                 break;
 
             case Token.NE:
-                result.append(" != ");
+                result.append(compress ? "!=" : " != ");
                 break;
 
             case Token.LE:
-                result.append(" <= ");
+                result.append(compress ? "<=" : " <= ");
                 break;
 
             case Token.LT:
-                result.append(" < ");
+                result.append(compress ? "<" : " < ");
                 break;
 
             case Token.GE:
-                result.append(" >= ");
+                result.append(compress ? ">=" : " >= ");
                 break;
 
             case Token.GT:
-                result.append(" > ");
+                result.append(compress ? ">" : " > ");
                 break;
 
             case Token.INSTANCEOF:
@@ -712,15 +766,15 @@
                 break;
 
             case Token.LSH:
-                result.append(" << ");
+                result.append(compress ? "<<" : " << ");
                 break;
 
             case Token.RSH:
-                result.append(" >> ");
+                result.append(compress ? ">>" : " >> ");
                 break;
 
             case Token.URSH:
-                result.append(" >>> ");
+                result.append(compress ? ">>>" : " >>> ");
                 break;
 
             case Token.TYPEOF:
@@ -748,31 +802,39 @@
                 break;
 
             case Token.INC:
+ if (compress && Token.ADD == prevToken)
+ result.append(' ');
                 result.append("++");
+                if (compress && Token.ADD == getNext(source, length, i))
+                    result.append(' ');
                 break;
 
             case Token.DEC:
+ if (compress && Token.SUB == prevToken)
+ result.append(' ');
                 result.append("--");
+                if (compress && Token.SUB == getNext(source, length, i))
+                    result.append(' ');
                 break;
 
             case Token.ADD:
-                result.append(" + ");
+                result.append(compress ? "+" : " + ");
                 break;
 
             case Token.SUB:
-                result.append(" - ");
+                result.append(compress ? "-" : " - ");
                 break;
 
             case Token.MUL:
-                result.append(" * ");
+                result.append(compress ? "*" : " * ");
                 break;
 
             case Token.DIV:
-                result.append(" / ");
+                result.append(compress ? "/" : " / ");
                 break;
 
             case Token.MOD:
-                result.append(" % ");
+                result.append(compress ? "%" : " % ");
                 break;
 
             case Token.COLONCOLON:
@@ -800,7 +862,7 @@
 
         if (!toSource) {
             // add that trailing newline if it's an outermost function.
-            if (!justFunctionBody)
+            if (!justFunctionBody && !compressnl)
                 result.append('\n');
         } else {
             if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
@@ -890,3 +952,111 @@
     private static final boolean printSource = false;
 
 }
+
+
+class TokenMapper {
+ private java.util.ArrayList functionBracePositions =
+        new java.util.ArrayList();
+ private java.util.ArrayList scopeReplacedTokens = new java.util.ArrayList();
+ private int tokenCount = 10;
+
+ // FIXME: this isn't the brightest way to accomplish this. Firstly, we need
+ // to be sure we aren't colliding with other things in the namespace!
+ private String getMappedToken(String token, boolean newMapping) {
+ String nt = null;
+        java.util.HashMap tokens = (java.util.HashMap)scopeReplacedTokens.get(scopeReplacedTokens.size()-1);
+ if (newMapping) {
+ nt = new String(Integer.toString(tokenCount++,26));
+ tokens.put(token, nt);
+ return nt;
+ }
+        String mapping = getTokenMapping(token);
+        if (mapping==null)
+            return token;
+        return mapping;
+ }
+
+ private boolean hasLocalTokenMapping(String token) {
+ if (scopeReplacedTokens.size() < 1)
+ return false;
+        java.util.HashMap tokens = (java.util.HashMap)(scopeReplacedTokens.get(scopeReplacedTokens.size()-1));
+ if (tokens.containsKey(token))
+ return true;
+ return false;
+ }
+
+ private String getTokenMapping(String token) {
+ for (int i=scopeReplacedTokens.size()-1; i>=0; i--) {
+            java.util.HashMap tokens = (java.util.HashMap)(scopeReplacedTokens.get(i));
+ if (tokens.containsKey(token))
+ return (String)tokens.get(token);
+ }
+ return null;
+ }
+
+ public int printCompressed(String source,
+ int offset,
+ boolean asQuotedString,
+ StringBuffer sb,
+ int prevToken,
+ boolean inArgsList,
+ int currentLevel) {
+ boolean newMapping = false;
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ String sourceStr = new String(str);
+ if (((prevToken == Token.VAR)&&(!hasLocalTokenMapping(sourceStr)))||(inArgsList))
+ newMapping = true;
+
+
+ if (((functionBracePositions.size()>0)&&(currentLevel>=(((Integer)functionBracePositions.get(functionBracePositions.size()-1)).intValue())))||(inArgsList))
+ if(prevToken != Token.DOT)
+ str = this.getMappedToken(str, newMapping);
+ if ((!inArgsList)&&(asQuotedString))
+ if((prevToken == Token.LC)||(prevToken == Token.COMMA))
+ str = sourceStr;
+
+ if(!asQuotedString){
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+
+ return offset + length;
+ }
+
+ public void enterNestingLevel(int braceNesting){
+ functionBracePositions.add(new Integer(braceNesting+1));
+ scopeReplacedTokens.add(new java.util.HashMap());
+ }
+
+ public void leaveNestingLevel(int braceNesting){
+ Integer bn = new Integer(braceNesting);
+ if ((functionBracePositions.contains(bn))&&(scopeReplacedTokens.size()>0)) {
+ // remove our mappings now!
+ int scopedSize = scopeReplacedTokens.size();
+ /*
+ HashMap tokens = (HashMap)(scopeReplacedTokens.get(scopedSize-1));
+ Iterator titer = (tokens.keySet()).iterator();
+ String key = null;
+ while(titer.hasNext()){
+ key = (String)titer.next();
+ // System.out.println("removing: "+key);
+ tokenMappings.remove(key);
+ }
+ */
+ scopeReplacedTokens.remove(scopedSize-1);
+ functionBracePositions.remove(bn);
+ }
+ }
+}
Index: src/org/mozilla/javascript/InterpreterData.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/InterpreterData.java,v
retrieving revision 1.53
diff -u -r1.53 InterpreterData.java
--- src/org/mozilla/javascript/InterpreterData.java 30 Aug 2005 10:05:42 -0000 1.53
+++ src/org/mozilla/javascript/InterpreterData.java 26 Jul 2006 23:16:27 -0000
@@ -102,6 +102,9 @@
     String encodedSource;
     int encodedSourceStart;
     int encodedSourceEnd;
+    
+    // Marcello: Added JSDoc
+    String jsDoc;
 
     int languageVersion;
 
@@ -154,6 +157,11 @@
         return itsSourceFile;
     }
 
+    public String getJSDoc()
+    {
+        return jsDoc;
+    }
+
     public boolean isGeneratedScript()
     {
         return ScriptRuntime.isGeneratedScript(itsSourceFile);
Index: src/org/mozilla/javascript/Parser.java
===================================================================
RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Parser.java,v
retrieving revision 1.104
diff -u -r1.104 Parser.java
--- src/org/mozilla/javascript/Parser.java 1 Jun 2006 14:30:19 -0000 1.104
+++ src/org/mozilla/javascript/Parser.java 26 Jul 2006 23:16:28 -0000
@@ -430,6 +430,9 @@
     {
         int syntheticType = functionType;
         int baseLineno = ts.getLineno();  // line number where source starts
+        
+        // Marcello: JSDoc addition
+        String jsDoc = ts.getJSDoc();
 
         int functionSourceStart = decompiler.markFunctionStart(functionType);
         String name;
@@ -476,6 +479,9 @@
             // of with object.
             fnNode.itsIgnoreDynamicScope = true;
         }
+        
+        // Marcello: JSDoc addition
+        fnNode.setJSDoc(jsDoc);
 
         int functionIndex = currentScriptOrFn.addFunction(fnNode);
 

_______________________________________________
dev-tech-js-engine mailing list
dev-tech-js-engine@...
https://lists.mozilla.org/listinfo/dev-tech-js-engine

 « Return to Thread: Rhino: JSDoc?