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);