* 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.
|
||||
*
|
||||
* @param app
|
||||
*
|
||||
* @throws DocException ...
|
||||
*/
|
||||
public DocApplication(Application app) throws DocException {
|
||||
public DocApplication(Application app) {
|
||||
super(app.getName(), APPLICATION);
|
||||
this.app = app;
|
||||
readProps();
|
||||
|
|
|
@ -52,7 +52,7 @@ public abstract class DocElement implements IPathElement {
|
|||
List tags = new Vector();
|
||||
List parameters = new Vector();
|
||||
|
||||
protected DocElement(String name, int type) throws DocException {
|
||||
protected DocElement(String name, int type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
|
|
@ -19,25 +19,25 @@ package helma.doc;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class DocException extends RuntimeException {
|
||||
String str;
|
||||
public class DocException extends Exception {
|
||||
|
||||
/**
|
||||
* Creates a new DocException object.
|
||||
*
|
||||
* @param str ...
|
||||
* @param msg ...
|
||||
*/
|
||||
public DocException(String str) {
|
||||
super(str);
|
||||
this.str = str;
|
||||
public DocException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DocException object.
|
||||
*
|
||||
*
|
||||
* @return ...
|
||||
* @param msg the exception message
|
||||
* @param t the cause
|
||||
*/
|
||||
public String getMessage() {
|
||||
return str;
|
||||
public DocException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,11 +16,16 @@
|
|||
|
||||
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.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.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -42,20 +47,16 @@ public class DocFunction extends DocResourceElement {
|
|||
/**
|
||||
* creates a new DocFunction object of type ACTION connected to another DocElement
|
||||
*/
|
||||
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[] lines = StringUtils.splitLines(res.getContent());
|
||||
DocFunction func = new DocFunction(name, res, parent, ACTION);
|
||||
String rawComment = "";
|
||||
try {
|
||||
DockenStream ts = getDockenStream (res);
|
||||
Point p = getPoint (ts);
|
||||
ts.getToken();
|
||||
rawComment = Util.getStringFromFile(res, p, getPoint(ts));
|
||||
rawComment = Util.chopComment (rawComment);
|
||||
} catch (IOException io) {
|
||||
io.printStackTrace();
|
||||
throw new DocException (io.toString());
|
||||
}
|
||||
TokenStreamInjector ts = getTokenStream (res);
|
||||
Point p = getPoint (ts);
|
||||
ts.getToken();
|
||||
rawComment = Util.extractString(lines, p, getPoint(ts));
|
||||
rawComment = Util.chopComment (rawComment);
|
||||
func.parseComment(rawComment);
|
||||
func.content = res.getContent();
|
||||
return func;
|
||||
|
@ -64,7 +65,7 @@ public class DocFunction extends DocResourceElement {
|
|||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
@ -73,35 +74,34 @@ public class DocFunction extends DocResourceElement {
|
|||
* reads a function file and creates DocFunction objects of type FUNCTION
|
||||
* 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();
|
||||
|
||||
try {
|
||||
String content = res.getContent();
|
||||
String[] lines = StringUtils.splitLines(content);
|
||||
String comment = "";
|
||||
|
||||
int token = Token.EMPTY;
|
||||
int lastToken = Token.EMPTY;
|
||||
Point endOfLastToken = null;
|
||||
Point endOfLastUsedToken = null;
|
||||
Point startOfFunctionBody = null;
|
||||
Point endOfFunctionBody = null;
|
||||
Point marker;
|
||||
|
||||
String lastNameString = null;
|
||||
String functionName = null;
|
||||
String context = null;
|
||||
|
||||
DockenStream ts = getDockenStream (res);
|
||||
TokenStreamInjector ts = getTokenStream (content);
|
||||
|
||||
while (!ts.eof()) {
|
||||
|
||||
// store the position of the last token
|
||||
endOfLastToken = getPoint (ts);
|
||||
|
||||
// store the position of the last token
|
||||
marker = getPoint (ts);
|
||||
// store last token
|
||||
lastToken = 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
|
||||
try {
|
||||
token = ts.getToken();
|
||||
|
@ -109,7 +109,13 @@ public class DocFunction extends DocResourceElement {
|
|||
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,
|
||||
// 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
|
||||
// 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;
|
||||
marker = getPoint(ts);
|
||||
marker.x -= (ts.getString().length() + 1);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -165,17 +168,13 @@ public class DocFunction extends DocResourceElement {
|
|||
|
||||
// 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;
|
||||
marker = p;
|
||||
marker.x -= 9;
|
||||
|
||||
// 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.
|
||||
|
@ -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
|
||||
DocFunction theFunction = newFunction (functionName, res, parent);
|
||||
theFunction.parseComment (rawComment);
|
||||
theFunction.parseComment (comment);
|
||||
vec.add (theFunction);
|
||||
|
||||
// subloop on the tokenstream: find the parameters of a function
|
||||
|
@ -208,7 +202,7 @@ public class DocFunction extends DocResourceElement {
|
|||
token = ts.getToken();
|
||||
int level = (token == Token.LC) ? 1 : 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
|
||||
try {
|
||||
token = ts.getToken();
|
||||
|
@ -221,17 +215,14 @@ public class DocFunction extends DocResourceElement {
|
|||
level--;
|
||||
}
|
||||
}
|
||||
endOfFunctionBody = getPoint(ts);
|
||||
|
||||
theFunction.content = Util.getStringFromFile(res, startOfFunctionBody, endOfFunctionBody);
|
||||
theFunction.content = Util.extractString(lines, marker, getPoint(ts));
|
||||
comment = "";
|
||||
|
||||
} // end if
|
||||
} // end while
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
throw new DocException (ex.toString());
|
||||
}
|
||||
|
||||
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;
|
||||
try {
|
||||
reader = new InputStreamReader(res.getInputStream());
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
throw new DocException (fnfe.toString());
|
||||
String content = null;
|
||||
if (src instanceof Resource) {
|
||||
reader = new InputStreamReader(((Resource) src).getInputStream());
|
||||
} else if (src instanceof String) {
|
||||
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();
|
||||
compilerEnv.initFromContext(Context.getCurrentContext());
|
||||
ErrorReporter errorReporter = Context.getCurrentContext().getErrorReporter();
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* from helma.framework.IPathElement. All macros, templates, actions etc
|
||||
* have the same prototype.
|
||||
|
|
|
@ -32,7 +32,7 @@ public class DocProperties extends DocResourceElement {
|
|||
|
||||
protected DocProperties(Resource res, ResourceProperties props,
|
||||
int index, DocElement parent)
|
||||
throws DocException, IOException {
|
||||
throws IOException {
|
||||
super(res.getShortName(), res, PROPERTIES);
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -70,9 +70,7 @@ public abstract class DocRepositoryElement extends DocElement {
|
|||
|
||||
if (res.exists()) {
|
||||
String rawComment = res.getContent();
|
||||
|
||||
parseComment(rawComment);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package helma.doc;
|
||||
|
||||
import helma.framework.repository.Resource;
|
||||
|
||||
import java.awt.Point;
|
||||
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 end of string to extract
|
||||
|
||||
* @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();
|
||||
int ct = 0;
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(res.getInputStream()));
|
||||
String line = "";
|
||||
while (line != null) {
|
||||
line = in.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
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());
|
||||
int to = Math.min(end.y + 1, lines.length);
|
||||
for (int i = start.y; i < to; i++) {
|
||||
int from = (i == start.y) ? start.x : 0;
|
||||
if (i == end.y && end.x < lines[i].length())
|
||||
buf.append(lines[i].substring(from, end.x));
|
||||
else
|
||||
buf.append(lines[i].substring(from));
|
||||
buf.append("\n");
|
||||
}
|
||||
return buf.toString().trim();
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
doc = new DocApplication(app);
|
||||
doc.readApplication();
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
throw new RuntimeException(x.toString(), x);
|
||||
}
|
||||
}
|
||||
return doc;
|
||||
|
|
|
@ -48,4 +48,13 @@ public class StringUtils {
|
|||
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