Refactor JsParser interface to be a static method; hide internal state.
Review by: bobv
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4938 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
index bbc8d3a..3666044 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
@@ -371,7 +371,6 @@
public String optimizeJavaScript(TreeLogger logger, String program)
throws UnableToCompleteException {
logger = logger.branch(TreeLogger.DEBUG, "Attempting to optimize JS", null);
- JsParser parser = new JsParser();
Reader r = new StringReader(program);
JsProgram jsProgram = new JsProgram();
JsScope topScope = jsProgram.getScope();
@@ -381,8 +380,7 @@
try {
SourceInfo sourceInfo = jsProgram.createSourceInfoSynthetic(
StandardLinkerContext.class, "Linker-derived JS");
- parser.setSourceInfo(sourceInfo);
- parser.parseInto(topScope, jsProgram.getGlobalBlock(), r, 1);
+ JsParser.parseInto(sourceInfo, topScope, jsProgram.getGlobalBlock(), r);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Unable to parse JavaScript", e);
throw new UnableToCompleteException();
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
index f35fb11..59ffee4 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
@@ -961,7 +961,6 @@
private boolean foundExplicitSourceOrSuperSource;
private final ObjAttrCvt<Generator> genAttrCvt = new ObjAttrCvt<Generator>(
Generator.class);
- private final JsParser jsParser = new JsParser();
private final JsProgram jsPgm = new JsProgram();
private final LinkerNameAttrCvt linkerNameAttrCvt = new LinkerNameAttrCvt();
private final ModuleDefLoader loader;
@@ -1034,9 +1033,8 @@
List<JsStatement> stmts;
try {
// TODO Provide more context here
- jsParser.setSourceInfo(jsPgm.createSourceInfoSynthetic(
- ModuleDefSchema.class, "Module.xml"));
- stmts = jsParser.parse(jsPgm.getScope(), r, startLineNumber);
+ stmts = JsParser.parse(jsPgm.createSourceInfo(startLineNumber,
+ moduleURL.toExternalForm()), jsPgm.getScope(), r);
} catch (IOException e) {
logger.log(TreeLogger.ERROR, "Error reading script source", e);
throw new UnableToCompleteException();
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
index 0bc1d6f..b514a13 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
@@ -65,7 +65,7 @@
private final String[] paramNames;
private final String source;
private final JsProgram program;
-
+
private JsniMethodImpl(String name, String source, String[] paramNames,
int line, String location, JsProgram program) {
this.name = name;
@@ -281,9 +281,8 @@
}
try {
- JsParser parser = new JsParser();
- parser.setSourceInfo(program.createSourceInfo(startLine, location));
- List<JsStatement> stmts = parser.parse(program.getScope(), r, startLine);
+ List<JsStatement> stmts = JsParser.parse(program.createSourceInfo(
+ startLine, location), program.getScope(), r);
return (JsFunction) ((JsExprStmt) stmts.get(0)).getExpression();
} catch (IOException e) {
diff --git a/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java b/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java
index afbeef1..3cc1cd9 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/FindJsniRefVisitor.java
@@ -16,6 +16,7 @@
package com.google.gwt.dev.jdt;
import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.JsParser;
import com.google.gwt.dev.js.JsParserException;
import com.google.gwt.dev.js.ast.JsContext;
@@ -107,7 +108,6 @@
private void findJsniRefsAccurately(MethodDeclaration methodDeclaration,
String jsniCode) throws InternalCompilerException {
- JsParser jsParser = new JsParser();
JsProgram jsProgram = new JsProgram();
String syntheticFnHeader = "function(";
@@ -127,7 +127,8 @@
StringReader sr = new StringReader(syntheticFnHeader + '\n' + jsniCode);
try {
// start at -1 to avoid counting our synthetic header
- List<JsStatement> result = jsParser.parse(jsProgram.getScope(), sr, -1);
+ List<JsStatement> result = JsParser.parse(SourceInfo.UNKNOWN,
+ jsProgram.getScope(), sr);
new JsVisitor() {
public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) {
String ident = x.getIdent();
@@ -160,7 +161,7 @@
String jsniRefString = readJsIdentifier(reader);
if (jsniRefString == null) {
// badly formatted identifier; skip to the next @ sign
- idx++;
+ idx++;
} else {
assert (jsniRefString.charAt(0) == '@');
jsniRefs.add(jsniRefString.substring(1));
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
index f4381b8..246a0a2 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
@@ -352,4 +352,9 @@
}
}
}
+
+ @Override
+ public String toString() {
+ return origin.toString();
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
index 0b57c9f..4ef81f4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/SourceOrigin.java
@@ -105,4 +105,9 @@
public int hashCode() {
return hash;
}
+
+ @Override
+ public String toString() {
+ return getFileName() + '(' + getStartLine() + ')';
+ }
}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index 99f9121..b451d7b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -120,7 +120,6 @@
private int[] currentSeparatorPositions;
- private final JsParser jsParser = new JsParser();
private final JsProgram jsProgram;
private JProgram program;
private List<TypeDeclaration> typeDecls = new ArrayList<TypeDeclaration>();
@@ -728,12 +727,9 @@
syntheticFnHeader += param.getName();
}
syntheticFnHeader += ')';
- StringReader sr = new StringReader(syntheticFnHeader + '\n' + jsniCode);
+ StringReader sr = new StringReader(syntheticFnHeader + ' ' + jsniCode);
try {
- // start at -1 to avoid counting our synthetic header
- // TODO: get the character position start correct
- jsParser.setSourceInfo(info);
- List<JsStatement> result = jsParser.parse(jsProgram.getScope(), sr, -1);
+ List<JsStatement> result = JsParser.parse(info, jsProgram.getScope(), sr);
JsExprStmt jsExprStmt = (JsExprStmt) result.get(0);
JsFunction jsFunction = (JsFunction) jsExprStmt.getExpression();
jsFunction.setFromJava(true);
diff --git a/dev/core/src/com/google/gwt/dev/js/JsParser.java b/dev/core/src/com/google/gwt/dev/js/JsParser.java
index 750f102..674b2b0 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsParser.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsParser.java
@@ -69,7 +69,6 @@
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.Stack;
@@ -78,14 +77,30 @@
*/
public class JsParser {
+ public static List<JsStatement> parse(SourceInfo rootSourceInfo,
+ JsScope scope, Reader r) throws IOException, JsParserException {
+ return new JsParser(scope.getProgram()).parseImpl(rootSourceInfo, scope, r);
+ }
+
+ public static void parseInto(SourceInfo rootSourceInfo, JsScope scope,
+ JsBlock block, Reader r) throws IOException, JsParserException {
+ List<JsStatement> childStmts = parse(rootSourceInfo, scope, r);
+ List<JsStatement> parentStmts = block.getStatements();
+ parentStmts.addAll(childStmts);
+ }
+
private JsProgram program;
- private SourceInfo rootSourceInfo = SourceInfo.UNKNOWN;
+
private final Stack<JsScope> scopeStack = new Stack<JsScope>();
private final Stack<SourceInfo> sourceInfoStack = new Stack<SourceInfo>();
- public JsParser() {
+ private JsParser(JsProgram program) {
+ this.program = program;
+ }
+
+ List<JsStatement> parseImpl(SourceInfo rootSourceInfo, JsScope scope, Reader r)
+ throws JsParserException, IOException {
// Create a custom error handler so that we can throw our own exceptions.
- //
Context.enter().setErrorReporter(new ErrorReporter() {
public void error(String msg, String loc, int ln, String src, int col) {
throw new UncheckedJsParserException(new JsParserException(msg, ln,
@@ -103,46 +118,26 @@
// Ignore warnings.
}
});
- }
-
- public List<JsStatement> parse(JsScope scope, Reader r, int startLine)
- throws IOException, JsParserException {
try {
// Parse using the Rhino parser.
//
- TokenStream ts = new TokenStream(r, "", startLine);
+ TokenStream ts = new TokenStream(r, rootSourceInfo.getFileName(),
+ rootSourceInfo.getStartLine());
Parser parser = new Parser(new IRFactory(ts));
Node topNode = (Node) parser.parse(ts);
// Map the Rhino AST to ours.
- //
- program = scope.getProgram();
pushScope(scope, rootSourceInfo);
List<JsStatement> stmts = mapStatements(topNode);
popScope();
-
return stmts;
} catch (UncheckedJsParserException e) {
throw e.getParserException();
+ } finally {
+ Context.exit();
}
}
- public void parseInto(JsScope scope, JsBlock block, Reader r, int startLine)
- throws IOException, JsParserException {
- List<JsStatement> childStmts = parse(scope, r, startLine);
- List<JsStatement> parentStmts = block.getStatements();
- for (Iterator<JsStatement> iter = childStmts.iterator(); iter.hasNext();) {
- parentStmts.add(iter.next());
- }
- }
-
- /**
- * Set the base SourceInfo object to use when creating new JS AST nodes.
- */
- public void setSourceInfo(SourceInfo sourceInfo) {
- rootSourceInfo = sourceInfo;
- }
-
private JsParserException createParserException(String msg, Node offender) {
// TODO: get source info
offender.getLineno();
@@ -155,8 +150,8 @@
private SourceInfo makeSourceInfo(Node node) {
SourceInfo parent = sourceInfoStack.peek();
- SourceInfo toReturn = program.createSourceInfo(node.getLineno()
- + parent.getStartLine() + 1, parent.getFileName());
+ SourceInfo toReturn = program.createSourceInfo(node.getLineno(),
+ parent.getFileName());
toReturn.copyMissingCorrelationsFrom(parent);
return toReturn;
}
@@ -884,7 +879,7 @@
case TokenStream.NULL:
return program.getNullLiteral();
-
+
case TokenStream.UNDEFINED:
return program.getUndefinedLiteral();
diff --git a/dev/core/src/com/google/gwt/dev/util/xml/ReflectiveParser.java b/dev/core/src/com/google/gwt/dev/util/xml/ReflectiveParser.java
index 81a6ffa..224d1ee 100644
--- a/dev/core/src/com/google/gwt/dev/util/xml/ReflectiveParser.java
+++ b/dev/core/src/com/google/gwt/dev/util/xml/ReflectiveParser.java
@@ -95,6 +95,19 @@
// Call the handler.
//
try {
+ // The line number is at the end of the text; subtract however many
+ // newlines the text contains.
+ for (int i = start, e = start + length, l = e - 1; i < e; ++i) {
+ switch (ch[i]) {
+ case '\r':
+ if (i < l && ch[i + 1] == '\n') {
+ continue;
+ }
+ // Intentional fall-through
+ case '\n':
+ --lineNumber;
+ }
+ }
final String text = String.valueOf(ch, start, length);
method.invokeText(lineNumber, text, schemaLevel);
} catch (UnableToCompleteException e) {
diff --git a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
index 66ba017..35431e5 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorAccuracyTest.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.js;
+import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsStatement;
import com.google.gwt.dev.js.ast.JsVisitor;
@@ -28,8 +29,6 @@
public class JsToStringGenerationVisitorAccuracyTest extends TestCase {
- private JsParser parser = new JsParser();
-
public void testAdditionPositive() throws Exception {
// x plus positive 3
doTest("x + +3");
@@ -135,8 +134,8 @@
}
private void doTest(String js) throws Exception {
- List<JsStatement> expected = parser.parse(new JsProgram().getScope(),
- new StringReader(js), 0);
+ List<JsStatement> expected = JsParser.parse(SourceInfo.UNKNOWN,
+ new JsProgram().getScope(), new StringReader(js));
List<JsStatement> actual = parse(expected, true);
ComparingVisitor.exec(expected, actual);
@@ -149,7 +148,7 @@
TextOutput text = new DefaultTextOutput(compact);
JsVisitor generator = new JsSourceGenerationVisitor(text);
generator.acceptList(expected);
- return parser.parse(new JsProgram().getScope(), new StringReader(
- text.toString()), 0);
+ return JsParser.parse(SourceInfo.UNKNOWN, new JsProgram().getScope(),
+ new StringReader(text.toString()));
}
}
diff --git a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorConcisenessTest.java b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorConcisenessTest.java
index edcf1c8..5e01daf 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorConcisenessTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsToStringGenerationVisitorConcisenessTest.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.js;
+import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsStatement;
import com.google.gwt.dev.js.ast.JsVisitor;
@@ -28,8 +29,6 @@
public class JsToStringGenerationVisitorConcisenessTest extends TestCase {
- private JsParser parser = new JsParser();
-
public void testComplexDecrement() throws Exception {
String output = parse("var x = -(-(-(--y)))");
assertEquals("var x=- - - --y", output);
@@ -76,8 +75,8 @@
}
private String parse(String js) throws Exception {
- List<JsStatement> statements = parser.parse(new JsProgram().getScope(),
- new StringReader(js), 0);
+ List<JsStatement> statements = JsParser.parse(SourceInfo.UNKNOWN,
+ new JsProgram().getScope(), new StringReader(js));
TextOutput text = new DefaultTextOutput(true);
JsVisitor generator = new JsToStringGenerationVisitor(text);
generator.acceptList(statements);