* Work on DocFunction to make it work with Rhino 1.6.
* Make DocFunction not a RuntimeException, and throw it only where needed. * Add TokenStreamInjector class to rhino to make TokenStream publicly available * Add StringUtils.splitLines()
This commit is contained in:
parent
578ecb148b
commit
bc8653a873
10 changed files with 103 additions and 123 deletions
BIN
lib/rhino.jar
BIN
lib/rhino.jar
Binary file not shown.
|
@ -35,11 +35,8 @@ public class DocApplication extends DocElement {
|
||||||
/**
|
/**
|
||||||
* Creates a new DocApplication object.
|
* Creates a new DocApplication object.
|
||||||
*
|
*
|
||||||
* @param app
|
|
||||||
*
|
|
||||||
* @throws DocException ...
|
|
||||||
*/
|
*/
|
||||||
public DocApplication(Application app) throws DocException {
|
public DocApplication(Application app) {
|
||||||
super(app.getName(), APPLICATION);
|
super(app.getName(), APPLICATION);
|
||||||
this.app = app;
|
this.app = app;
|
||||||
readProps();
|
readProps();
|
||||||
|
|
|
@ -52,7 +52,7 @@ public abstract class DocElement implements IPathElement {
|
||||||
List tags = new Vector();
|
List tags = new Vector();
|
||||||
List parameters = new Vector();
|
List parameters = new Vector();
|
||||||
|
|
||||||
protected DocElement(String name, int type) throws DocException {
|
protected DocElement(String name, int type) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,25 +19,25 @@ package helma.doc;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DocException extends RuntimeException {
|
public class DocException extends Exception {
|
||||||
String str;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new DocException object.
|
* Creates a new DocException object.
|
||||||
*
|
*
|
||||||
* @param str ...
|
* @param msg ...
|
||||||
*/
|
*/
|
||||||
public DocException(String str) {
|
public DocException(String msg) {
|
||||||
super(str);
|
super(msg);
|
||||||
this.str = str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Creates a new DocException object.
|
||||||
*
|
*
|
||||||
*
|
* @param msg the exception message
|
||||||
* @return ...
|
* @param t the cause
|
||||||
*/
|
*/
|
||||||
public String getMessage() {
|
public DocException(String msg, Throwable t) {
|
||||||
return str;
|
super(msg, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,16 @@
|
||||||
|
|
||||||
package helma.doc;
|
package helma.doc;
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Vector;
|
|
||||||
import org.mozilla.javascript.*;
|
|
||||||
import helma.framework.repository.Resource;
|
import helma.framework.repository.Resource;
|
||||||
|
import helma.util.StringUtils;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -44,18 +49,14 @@ public class DocFunction extends DocResourceElement {
|
||||||
*/
|
*/
|
||||||
public static DocFunction newAction(Resource res, DocElement parent) throws IOException {
|
public static DocFunction newAction(Resource res, DocElement parent) throws IOException {
|
||||||
String name = res.getBaseName();
|
String name = res.getBaseName();
|
||||||
|
String[] lines = StringUtils.splitLines(res.getContent());
|
||||||
DocFunction func = new DocFunction(name, res, parent, ACTION);
|
DocFunction func = new DocFunction(name, res, parent, ACTION);
|
||||||
String rawComment = "";
|
String rawComment = "";
|
||||||
try {
|
TokenStreamInjector ts = getTokenStream (res);
|
||||||
DockenStream ts = getDockenStream (res);
|
|
||||||
Point p = getPoint (ts);
|
Point p = getPoint (ts);
|
||||||
ts.getToken();
|
ts.getToken();
|
||||||
rawComment = Util.getStringFromFile(res, p, getPoint(ts));
|
rawComment = Util.extractString(lines, p, getPoint(ts));
|
||||||
rawComment = Util.chopComment (rawComment);
|
rawComment = Util.chopComment (rawComment);
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
throw new DocException (io.toString());
|
|
||||||
}
|
|
||||||
func.parseComment(rawComment);
|
func.parseComment(rawComment);
|
||||||
func.content = res.getContent();
|
func.content = res.getContent();
|
||||||
return func;
|
return func;
|
||||||
|
@ -64,7 +65,7 @@ public class DocFunction extends DocResourceElement {
|
||||||
/**
|
/**
|
||||||
* reads a function file and creates independent DocFunction objects of type FUNCTION
|
* reads a function file and creates independent DocFunction objects of type FUNCTION
|
||||||
*/
|
*/
|
||||||
public static DocFunction[] newFunctions(Resource res) {
|
public static DocFunction[] newFunctions(Resource res) throws IOException {
|
||||||
return newFunctions(res, null);
|
return newFunctions(res, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,35 +74,34 @@ public class DocFunction extends DocResourceElement {
|
||||||
* reads a function file and creates DocFunction objects of type FUNCTION
|
* reads a function file and creates DocFunction objects of type FUNCTION
|
||||||
* connected to another DocElement.
|
* connected to another DocElement.
|
||||||
*/
|
*/
|
||||||
public static DocFunction[] newFunctions(Resource res, DocElement parent) {
|
public static DocFunction[] newFunctions(Resource res, DocElement parent)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
Vector vec = new Vector();
|
Vector vec = new Vector();
|
||||||
|
|
||||||
try {
|
String content = res.getContent();
|
||||||
|
String[] lines = StringUtils.splitLines(content);
|
||||||
|
String comment = "";
|
||||||
|
|
||||||
int token = Token.EMPTY;
|
int token = Token.EMPTY;
|
||||||
int lastToken = Token.EMPTY;
|
int lastToken = Token.EMPTY;
|
||||||
Point endOfLastToken = null;
|
Point marker;
|
||||||
Point endOfLastUsedToken = null;
|
|
||||||
Point startOfFunctionBody = null;
|
|
||||||
Point endOfFunctionBody = null;
|
|
||||||
|
|
||||||
String lastNameString = null;
|
String lastNameString = null;
|
||||||
String functionName = null;
|
String functionName = null;
|
||||||
String context = null;
|
String context = null;
|
||||||
|
|
||||||
DockenStream ts = getDockenStream (res);
|
TokenStreamInjector ts = getTokenStream (content);
|
||||||
|
|
||||||
while (!ts.eof()) {
|
while (!ts.eof()) {
|
||||||
|
|
||||||
// store the position of the last token
|
// store the position of the last token
|
||||||
endOfLastToken = getPoint (ts);
|
marker = getPoint (ts);
|
||||||
|
|
||||||
// store last token
|
// store last token
|
||||||
lastToken = token;
|
lastToken = token;
|
||||||
|
|
||||||
// now get a new token
|
// now get a new token
|
||||||
// regular expression syntax is troublesome for the DockenStream
|
// regular expression syntax is troublesome for the TokenStream
|
||||||
// we can safely ignore syntax errors in regular expressions here
|
// we can safely ignore syntax errors in regular expressions here
|
||||||
try {
|
try {
|
||||||
token = ts.getToken();
|
token = ts.getToken();
|
||||||
|
@ -109,7 +109,13 @@ public class DocFunction extends DocResourceElement {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == Token.LC) {
|
if (token == Token.EOL) {
|
||||||
|
|
||||||
|
String c = Util.extractString(lines, marker, getPoint(ts));
|
||||||
|
if (c.startsWith("/**"))
|
||||||
|
comment = c;
|
||||||
|
|
||||||
|
} else if (token == Token.LC) {
|
||||||
|
|
||||||
// when we come across a left brace outside of a function,
|
// when we come across a left brace outside of a function,
|
||||||
// we store the current string of the stream, it might be
|
// we store the current string of the stream, it might be
|
||||||
|
@ -134,11 +140,8 @@ public class DocFunction extends DocResourceElement {
|
||||||
|
|
||||||
// this may be the start of a name chain declaring a function
|
// this may be the start of a name chain declaring a function
|
||||||
// e.g. Number.prototype.functionName = function() { }
|
// e.g. Number.prototype.functionName = function() { }
|
||||||
startOfFunctionBody = getPoint(ts);
|
marker = getPoint(ts);
|
||||||
startOfFunctionBody.x -= (ts.getString().length() + 1);
|
marker.x -= (ts.getString().length() + 1);
|
||||||
|
|
||||||
// set pointer to end of last function to the token before the name
|
|
||||||
endOfLastUsedToken = endOfLastToken;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -165,17 +168,13 @@ public class DocFunction extends DocResourceElement {
|
||||||
|
|
||||||
// set the pointer for the start of the actual function body
|
// set the pointer for the start of the actual function body
|
||||||
// to the letter f of the function word
|
// to the letter f of the function word
|
||||||
startOfFunctionBody = p;
|
marker = p;
|
||||||
startOfFunctionBody.x -= 9;
|
marker.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
|
// set stream to next token, so that name of the
|
||||||
// function is the stream's current string
|
// function is the stream's current string
|
||||||
token = ts.getToken();
|
token = ts.getToken();
|
||||||
functionName = ts.getString();
|
functionName = ts.getString();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// it's a different kind of function declaration.
|
// it's a different kind of function declaration.
|
||||||
|
@ -185,14 +184,9 @@ public class DocFunction extends DocResourceElement {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the comment from the file (unfortunately, the stream simply skips comments) ...
|
|
||||||
String rawComment = Util.getStringFromFile(res, endOfLastUsedToken, startOfFunctionBody).trim ();
|
|
||||||
// .. and clean it
|
|
||||||
rawComment = Util.chopComment (rawComment);
|
|
||||||
|
|
||||||
// create the function object
|
// create the function object
|
||||||
DocFunction theFunction = newFunction (functionName, res, parent);
|
DocFunction theFunction = newFunction (functionName, res, parent);
|
||||||
theFunction.parseComment (rawComment);
|
theFunction.parseComment (comment);
|
||||||
vec.add (theFunction);
|
vec.add (theFunction);
|
||||||
|
|
||||||
// subloop on the tokenstream: find the parameters of a function
|
// subloop on the tokenstream: find the parameters of a function
|
||||||
|
@ -208,7 +202,7 @@ public class DocFunction extends DocResourceElement {
|
||||||
token = ts.getToken();
|
token = ts.getToken();
|
||||||
int level = (token == Token.LC) ? 1 : 0;
|
int level = (token == Token.LC) ? 1 : 0;
|
||||||
while (!ts.eof() && level > 0) {
|
while (!ts.eof() && level > 0) {
|
||||||
// regular expression syntax is troublesome for the DockenStream
|
// regular expression syntax is troublesome for the TokenStream
|
||||||
// we don't need them here, so we just ignore such an error
|
// we don't need them here, so we just ignore such an error
|
||||||
try {
|
try {
|
||||||
token = ts.getToken();
|
token = ts.getToken();
|
||||||
|
@ -221,17 +215,14 @@ public class DocFunction extends DocResourceElement {
|
||||||
level--;
|
level--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endOfFunctionBody = getPoint(ts);
|
|
||||||
|
|
||||||
theFunction.content = Util.getStringFromFile(res, startOfFunctionBody, endOfFunctionBody);
|
theFunction.content = Util.extractString(lines, marker, getPoint(ts));
|
||||||
|
comment = "";
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
} // end while
|
} // end while
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new DocException (ex.toString());
|
|
||||||
}
|
|
||||||
return (DocFunction[]) vec.toArray(new DocFunction[0]);
|
return (DocFunction[]) vec.toArray(new DocFunction[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,37 +237,45 @@ public class DocFunction extends DocResourceElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a rhino token stream for a given file
|
* Creates a rhino token stream for a given file.
|
||||||
|
* @param src the JS source, either as Resource or String object
|
||||||
|
* @return a TokenStream wrapper
|
||||||
|
* @throws IOException if an I/O exception was raised
|
||||||
*/
|
*/
|
||||||
protected static DockenStream getDockenStream (Resource res) throws IOException {
|
protected static TokenStreamInjector getTokenStream (Object src) throws IOException {
|
||||||
|
// TODO the TokenStreamInjector is really just a hack, and we shouldn't
|
||||||
|
// interact with the rhino TokenStream class directly. The proper way to
|
||||||
|
// go would be to use the public Parser class to parse the input, and walk
|
||||||
|
// through the parse tree and extract the comments manually.
|
||||||
|
// As a result of our approach, the TokenStream member in our Parser instance
|
||||||
|
// will be null, resulting in a NullPointerException when an error is
|
||||||
|
// encountered. For the time being, this is something we can live with.
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try {
|
String content = null;
|
||||||
reader = new InputStreamReader(res.getInputStream());
|
if (src instanceof Resource) {
|
||||||
} catch (FileNotFoundException fnfe) {
|
reader = new InputStreamReader(((Resource) src).getInputStream());
|
||||||
fnfe.printStackTrace();
|
} else if (src instanceof String) {
|
||||||
throw new DocException (fnfe.toString());
|
content = (String) src;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("src must be either a Resource or a String");
|
||||||
}
|
}
|
||||||
// String name = res.getName();
|
|
||||||
Integer line = new Integer(0);
|
|
||||||
CompilerEnvirons compilerEnv = new CompilerEnvirons();
|
CompilerEnvirons compilerEnv = new CompilerEnvirons();
|
||||||
compilerEnv.initFromContext(Context.getCurrentContext());
|
compilerEnv.initFromContext(Context.getCurrentContext());
|
||||||
ErrorReporter errorReporter = Context.getCurrentContext().getErrorReporter();
|
ErrorReporter errorReporter = Context.getCurrentContext().getErrorReporter();
|
||||||
Parser parser = new Parser(compilerEnv, errorReporter);
|
Parser parser = new Parser(compilerEnv, errorReporter);
|
||||||
return new DockenStream (parser, reader, null, line);
|
return new TokenStreamInjector (parser, reader, content, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a pointer to the current position in the DockenStream
|
* Returns a pointer to the current position in the TokenStream
|
||||||
|
* @param ts the TokenStream
|
||||||
|
* @return the current position
|
||||||
*/
|
*/
|
||||||
protected static Point getPoint (DockenStream ts) {
|
protected static Point getPoint (TokenStreamInjector ts) {
|
||||||
return new Point (ts.getOffset(), ts.getLineno());
|
return new Point (ts.getOffset(), ts.getLineno());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* from helma.framework.IPathElement. All macros, templates, actions etc
|
* from helma.framework.IPathElement. All macros, templates, actions etc
|
||||||
* have the same prototype.
|
* have the same prototype.
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class DocProperties extends DocResourceElement {
|
||||||
|
|
||||||
protected DocProperties(Resource res, ResourceProperties props,
|
protected DocProperties(Resource res, ResourceProperties props,
|
||||||
int index, DocElement parent)
|
int index, DocElement parent)
|
||||||
throws DocException, IOException {
|
throws IOException {
|
||||||
super(res.getShortName(), res, PROPERTIES);
|
super(res.getShortName(), res, PROPERTIES);
|
||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
|
@ -61,7 +61,7 @@ public abstract class DocRepositoryElement extends DocElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkCommentFiles() throws DocException, IOException {
|
private void checkCommentFiles() throws IOException {
|
||||||
if (repos == null) {
|
if (repos == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,9 +70,7 @@ public abstract class DocRepositoryElement extends DocElement {
|
||||||
|
|
||||||
if (res.exists()) {
|
if (res.exists()) {
|
||||||
String rawComment = res.getContent();
|
String rawComment = res.getContent();
|
||||||
|
|
||||||
parseComment(rawComment);
|
parseComment(rawComment);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package helma.doc;
|
package helma.doc;
|
||||||
|
|
||||||
import helma.framework.repository.Resource;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
@ -70,43 +68,22 @@ public final class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reads a part of a file defined by two points
|
* Extract a part of a file defined by two points from a String array
|
||||||
|
* @param lines an array of lines
|
||||||
* @param start of string to extract defined by column x and row y
|
* @param start of string to extract defined by column x and row y
|
||||||
|
|
||||||
* @param end of string to extract
|
* @param end of string to extract
|
||||||
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static String getStringFromFile (Resource res, Point start, Point end) {
|
public static String extractString (String[] lines, Point start, Point end) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
int ct = 0;
|
int to = Math.min(end.y + 1, lines.length);
|
||||||
try {
|
for (int i = start.y; i < to; i++) {
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(res.getInputStream()));
|
int from = (i == start.y) ? start.x : 0;
|
||||||
String line = "";
|
if (i == end.y && end.x < lines[i].length())
|
||||||
while (line != null) {
|
buf.append(lines[i].substring(from, end.x));
|
||||||
line = in.readLine();
|
else
|
||||||
if (line == null) {
|
buf.append(lines[i].substring(from));
|
||||||
break;
|
buf.append("\n");
|
||||||
}
|
|
||||||
if ((ct > start.y) && (ct < end.y)) {
|
|
||||||
buf.append(line).append("\n");
|
|
||||||
} else if (ct == start.y) {
|
|
||||||
if (start.y==end.y) {
|
|
||||||
buf.append (line.substring (start.x, end.x));
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
buf.append(line.substring(start.x, line.length())).append("\n");
|
|
||||||
}
|
|
||||||
} else if (ct == end.y) {
|
|
||||||
buf.append(line.substring(0, end.x));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ct++;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println(e.getMessage());
|
|
||||||
}
|
}
|
||||||
return buf.toString().trim();
|
return buf.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,7 @@ public class RhinoEngine implements ScriptingEngine {
|
||||||
doc = new DocApplication(app);
|
doc = new DocApplication(app);
|
||||||
doc.readApplication();
|
doc.readApplication();
|
||||||
} catch (IOException x) {
|
} catch (IOException x) {
|
||||||
throw new RuntimeException(x.toString());
|
throw new RuntimeException(x.toString(), x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return doc;
|
return doc;
|
||||||
|
|
|
@ -48,4 +48,13 @@ public class StringUtils {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a string into an array of lines.
|
||||||
|
* @param str the string to split
|
||||||
|
* @return an array of lines
|
||||||
|
*/
|
||||||
|
public static String[] splitLines(String str) {
|
||||||
|
return str.split("\\r|\\n|\\r\\n");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue