rewrote the method for parsing function files so that it handles
the various ways of declaring functions in rhino
This commit is contained in:
parent
eee11438d7
commit
54f60eecef
1 changed files with 140 additions and 39 deletions
|
@ -19,10 +19,7 @@ package helma.doc;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import org.mozilla.javascript.TokenStream;
|
import org.mozilla.javascript.*;
|
||||||
import org.mozilla.javascript.Token;
|
|
||||||
import org.mozilla.javascript.Context;
|
|
||||||
import org.mozilla.javascript.CompilerEnvirons;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -76,55 +73,159 @@ public class DocFunction extends DocFileElement {
|
||||||
* connected to another DocElement.
|
* connected to another DocElement.
|
||||||
*/
|
*/
|
||||||
public static DocFunction[] newFunctions(File location, DocElement parent) {
|
public static DocFunction[] newFunctions(File location, DocElement parent) {
|
||||||
|
|
||||||
Vector vec = new Vector();
|
Vector vec = new Vector();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// the function file:
|
|
||||||
|
int token = Token.EMPTY;
|
||||||
|
int lastToken = Token.EMPTY;
|
||||||
|
Point endOfLastToken = null;
|
||||||
|
Point endOfLastUsedToken = null;
|
||||||
|
Point startOfFunctionBody = null;
|
||||||
|
Point endOfFunctionBody = null;
|
||||||
|
|
||||||
|
String lastNameString = null;
|
||||||
|
String functionName = null;
|
||||||
|
String context = null;
|
||||||
|
|
||||||
TokenStream ts = getTokenStream (location);
|
TokenStream ts = getTokenStream (location);
|
||||||
DocFunction curFunction = null;
|
|
||||||
Point curFunctionStart = null;
|
|
||||||
while (!ts.eof()) {
|
while (!ts.eof()) {
|
||||||
|
|
||||||
// store the position of the last token
|
// store the position of the last token
|
||||||
Point endOfLastToken = getPoint (ts);
|
endOfLastToken = getPoint (ts);
|
||||||
// new token
|
|
||||||
int tok = ts.getToken();
|
// store last token
|
||||||
|
lastToken = token;
|
||||||
// if we're currently parsing a functionbody and come to the start
|
|
||||||
// of the next function or eof -> read function body
|
// now get a new token
|
||||||
if (curFunction != null && (tok== Token.FUNCTION || ts.eof())) {
|
// regular expression syntax is troublesome for the TokenStream
|
||||||
curFunction.content = "function " + Util.getStringFromFile(location, curFunctionStart, endOfLastToken);
|
// we can safely ignore syntax errors in regular expressions here
|
||||||
|
try {
|
||||||
|
token = ts.getToken();
|
||||||
|
} catch(Exception anything) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok == Token.FUNCTION) {
|
if (token == Token.LC) {
|
||||||
// store the function start for parsing the function body later
|
|
||||||
curFunctionStart = getPoint (ts);
|
// when we come across a left brace outside of a function,
|
||||||
// get and chop the comment
|
// we store the current string of the stream, it might be
|
||||||
String rawComment = Util.getStringFromFile(location, endOfLastToken, getPoint (ts)).trim ();
|
// a function object declaration
|
||||||
|
// e.g. HttpClient = { func1:function()...}
|
||||||
|
context = ts.getString();
|
||||||
|
|
||||||
|
} else if (token == Token.RC && context != null) {
|
||||||
|
|
||||||
|
// when we come across a right brace outside of a function,
|
||||||
|
// we reset the current context cache
|
||||||
|
context = null;
|
||||||
|
|
||||||
|
} else if (token == Token.NAME) {
|
||||||
|
|
||||||
|
// store all names, the last one before a function
|
||||||
|
// declaration may be used as its name
|
||||||
|
|
||||||
|
if (lastToken != Token.DOT) {
|
||||||
|
|
||||||
|
lastNameString = ts.getString();
|
||||||
|
|
||||||
|
// this may be the start of a name chain declaring a function
|
||||||
|
// e.g. Number.prototype.functionName = function() { }
|
||||||
|
startOfFunctionBody = getPoint(ts);
|
||||||
|
startOfFunctionBody.x -= (ts.getString().length() + 1);
|
||||||
|
|
||||||
|
// set pointer to end of last function to the token before the name
|
||||||
|
endOfLastUsedToken = endOfLastToken;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// token in front of the name was a dot, so we connect the
|
||||||
|
// names that way
|
||||||
|
lastNameString += "." + ts.getString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (token == Token.FUNCTION) {
|
||||||
|
|
||||||
|
// store the end of the function word
|
||||||
|
Point p = getPoint(ts);
|
||||||
|
|
||||||
|
// look at the next token:
|
||||||
|
int peekToken = ts.peekToken();
|
||||||
|
|
||||||
|
// depending of the style of the declaration we already have all we need
|
||||||
|
// or need to fetch the name from the next token:
|
||||||
|
if (peekToken == Token.NAME) {
|
||||||
|
|
||||||
|
// if the token after FUNCTION is NAME, it's the usual function
|
||||||
|
// declaration like this: function abc() {}
|
||||||
|
|
||||||
|
// set the pointer for the start of the actual function body
|
||||||
|
// to the letter f of the function word
|
||||||
|
startOfFunctionBody = p;
|
||||||
|
startOfFunctionBody.x -= 9;
|
||||||
|
|
||||||
|
// lastToken should be the last thing that didn't belong to this function
|
||||||
|
endOfLastUsedToken = endOfLastToken;
|
||||||
|
|
||||||
|
// set stream to next token, so that name of the
|
||||||
|
// function is the stream's current string
|
||||||
|
token = ts.getToken();
|
||||||
|
functionName = ts.getString();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// it's a different kind of function declaration.
|
||||||
|
// the function name is the last found NAME-token
|
||||||
|
// if context is set, prepend it to the function name
|
||||||
|
functionName = (context != null) ? context + "." + lastNameString : lastNameString;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the comment from the file (unfortunately, the stream simply skips comments) ...
|
||||||
|
String rawComment = Util.getStringFromFile(location, endOfLastUsedToken, startOfFunctionBody).trim ();
|
||||||
|
// .. and clean it
|
||||||
rawComment = Util.chopComment (rawComment);
|
rawComment = Util.chopComment (rawComment);
|
||||||
// position stream at function name token
|
|
||||||
tok = ts.getToken();
|
// create the function object
|
||||||
// get the name and create the function object
|
DocFunction theFunction = newFunction (functionName, location, parent);
|
||||||
String name = ts.getString();
|
theFunction.parseComment (rawComment);
|
||||||
curFunction = newFunction (name, location, parent);
|
vec.add (theFunction);
|
||||||
curFunction.parseComment (rawComment);
|
|
||||||
vec.add (curFunction);
|
|
||||||
|
|
||||||
// subloop on the tokenstream: find the parameters of a function
|
// subloop on the tokenstream: find the parameters of a function
|
||||||
// only if it's a function (and not a macro or an action)
|
while (!ts.eof() && token != Token.RP) {
|
||||||
if (curFunction.type == FUNCTION) {
|
token = ts.getToken();
|
||||||
while (!ts.eof() && tok != Token.RP) {
|
if (token==Token.NAME && theFunction.type == FUNCTION) {
|
||||||
// store the position of the last token
|
// add names of parameter only for functions, not for macros or actions
|
||||||
endOfLastToken = getPoint (ts);
|
theFunction.addParameter (ts.getString());
|
||||||
// new token
|
|
||||||
tok = ts.getToken();
|
|
||||||
if (tok==Token.NAME) {
|
|
||||||
curFunction.addParameter (ts.getString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end if
|
|
||||||
|
|
||||||
}
|
// subloop on the tokenstream: find the closing right bracket of the function
|
||||||
|
token = ts.getToken();
|
||||||
|
int level = (token == Token.LC) ? 1 : 0;
|
||||||
|
while (!ts.eof() && level > 0) {
|
||||||
|
// regular expression syntax is troublesome for the TokenStream
|
||||||
|
// we don't need them here, so we just ignore such an error
|
||||||
|
try {
|
||||||
|
token = ts.getToken();
|
||||||
|
} catch(Exception anything) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (token == Token.LC) {
|
||||||
|
level++;
|
||||||
|
} else if (token == Token.RC) {
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endOfFunctionBody = getPoint(ts);
|
||||||
|
|
||||||
|
theFunction.content = Util.getStringFromFile(location, startOfFunctionBody, endOfFunctionBody);
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
} // end while
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
|
Loading…
Add table
Reference in a new issue