7106166: (javac) re-factor EndPos parser

Reviewed-by: jjg
This commit is contained in:
Kumar Srinivasan 2011-11-14 15:11:10 -08:00
parent ca1deee4d3
commit b7094ba03c
16 changed files with 274 additions and 225 deletions

View file

@ -59,6 +59,7 @@ import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.comp.MemberEnter;
import com.sun.tools.javac.comp.Resolve; import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
@ -140,8 +141,8 @@ public class JavacTrees extends Trees {
} }
public long getEndPosition(CompilationUnitTree file, Tree tree) { public long getEndPosition(CompilationUnitTree file, Tree tree) {
Map<JCTree,Integer> endPositions = ((JCCompilationUnit) file).endPositions; EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
return TreeInfo.getEndPos((JCTree) tree, endPositions); return TreeInfo.getEndPos((JCTree) tree, endPosTable);
} }
}; };
} }

View file

@ -40,6 +40,7 @@ import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.parser.EndPosTable;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Flags.BLOCK;
@ -127,7 +128,7 @@ public class Lower extends TreeTranslator {
/** A hash table mapping syntax trees to their ending source positions. /** A hash table mapping syntax trees to their ending source positions.
*/ */
Map<JCTree, Integer> endPositions; EndPosTable endPosTable;
/************************************************************************** /**************************************************************************
* Global mappings * Global mappings
@ -2195,9 +2196,8 @@ public class Lower extends TreeTranslator {
} else { } else {
make_at(tree.pos()); make_at(tree.pos());
T result = super.translate(tree); T result = super.translate(tree);
if (endPositions != null && result != tree) { if (endPosTable != null && result != tree) {
Integer endPos = endPositions.remove(tree); endPosTable.replaceTree(tree, result);
if (endPos != null) endPositions.put(result, endPos);
} }
return result; return result;
} }
@ -3675,7 +3675,7 @@ public class Lower extends TreeTranslator {
try { try {
attrEnv = env; attrEnv = env;
this.make = make; this.make = make;
endPositions = env.toplevel.endPositions; endPosTable = env.toplevel.endPositions;
currentClass = null; currentClass = null;
currentMethodDef = null; currentMethodDef = null;
outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null; outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null;
@ -3704,7 +3704,7 @@ public class Lower extends TreeTranslator {
// note that recursive invocations of this method fail hard // note that recursive invocations of this method fail hard
attrEnv = null; attrEnv = null;
this.make = null; this.make = null;
endPositions = null; endPosTable = null;
currentClass = null; currentClass = null;
currentMethodDef = null; currentMethodDef = null;
outermostClassDef = null; outermostClassDef = null;

View file

@ -31,6 +31,7 @@ import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.parser.EndPosTable;
/** This class contains the CharacterRangeTable for some method /** This class contains the CharacterRangeTable for some method
* and the hashtable for mapping trees or lists of trees to their * and the hashtable for mapping trees or lists of trees to their
@ -54,9 +55,9 @@ implements CRTFlags {
*/ */
private Map<Object,SourceRange> positions = new HashMap<Object,SourceRange>(); private Map<Object,SourceRange> positions = new HashMap<Object,SourceRange>();
/** The hashtable for ending positions stored in the parser. /** The object for ending positions stored in the parser.
*/ */
private Map<JCTree, Integer> endPositions; private EndPosTable endPosTable;
/** The tree of the method this table is intended for. /** The tree of the method this table is intended for.
* We should traverse this tree to get source ranges. * We should traverse this tree to get source ranges.
@ -65,9 +66,9 @@ implements CRTFlags {
/** Constructor /** Constructor
*/ */
public CRTable(JCTree.JCMethodDecl tree, Map<JCTree, Integer> endPositions) { public CRTable(JCTree.JCMethodDecl tree, EndPosTable endPosTable) {
this.methodTree = tree; this.methodTree = tree;
this.endPositions = endPositions; this.endPosTable = endPosTable;
} }
/** Create a new CRTEntry and add it to the entries. /** Create a new CRTEntry and add it to the entries.
@ -534,10 +535,7 @@ implements CRTFlags {
if (tree == null) return Position.NOPOS; if (tree == null) return Position.NOPOS;
if (tree.hasTag(JCTree.Tag.BLOCK)) if (tree.hasTag(JCTree.Tag.BLOCK))
return ((JCBlock) tree).endpos; return ((JCBlock) tree).endpos;
Integer endpos = endPositions.get(tree); return endPosTable.getEndPos(tree);
if (endpos != null)
return endpos.intValue();
return Position.NOPOS;
} }
} }

View file

@ -26,8 +26,6 @@
package com.sun.tools.javac.jvm; package com.sun.tools.javac.jvm;
import java.util.*; import java.util.*;
import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
@ -39,6 +37,7 @@ import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.jvm.Code.*; import com.sun.tools.javac.jvm.Code.*;
import com.sun.tools.javac.jvm.Items.*; import com.sun.tools.javac.jvm.Items.*;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
@ -197,9 +196,10 @@ public class Gen extends JCTree.Visitor {
*/ */
private int nerrs = 0; private int nerrs = 0;
/** A hash table mapping syntax trees to their ending source positions. /** An object containing mappings of syntax trees to their
* ending source positions.
*/ */
private Map<JCTree, Integer> endPositions; EndPosTable endPosTable;
/** Generate code to load an integer constant. /** Generate code to load an integer constant.
* @param n The integer to be loaded. * @param n The integer to be loaded.
@ -482,20 +482,14 @@ public class Gen extends JCTree.Visitor {
JCStatement init = make.at(vdef.pos()). JCStatement init = make.at(vdef.pos()).
Assignment(sym, vdef.init); Assignment(sym, vdef.init);
initCode.append(init); initCode.append(init);
if (endPositions != null) { endPosTable.replaceTree(vdef, init);
Integer endPos = endPositions.remove(vdef);
if (endPos != null) endPositions.put(init, endPos);
}
} else if (sym.getConstValue() == null) { } else if (sym.getConstValue() == null) {
// Initialize class (static) variables only if // Initialize class (static) variables only if
// they are not compile-time constants. // they are not compile-time constants.
JCStatement init = make.at(vdef.pos). JCStatement init = make.at(vdef.pos).
Assignment(sym, vdef.init); Assignment(sym, vdef.init);
clinitCode.append(init); clinitCode.append(init);
if (endPositions != null) { endPosTable.replaceTree(vdef, init);
Integer endPos = endPositions.remove(vdef);
if (endPos != null) endPositions.put(init, endPos);
}
} else { } else {
checkStringConstant(vdef.init.pos(), sym.getConstValue()); checkStringConstant(vdef.init.pos(), sym.getConstValue());
} }
@ -2217,7 +2211,7 @@ public class Gen extends JCTree.Visitor {
attrEnv = env; attrEnv = env;
ClassSymbol c = cdef.sym; ClassSymbol c = cdef.sym;
this.toplevel = env.toplevel; this.toplevel = env.toplevel;
this.endPositions = toplevel.endPositions; this.endPosTable = toplevel.endPositions;
// If this is a class definition requiring Miranda methods, // If this is a class definition requiring Miranda methods,
// add them. // add them.
if (generateIproxies && if (generateIproxies &&
@ -2253,7 +2247,7 @@ public class Gen extends JCTree.Visitor {
attrEnv = null; attrEnv = null;
this.env = null; this.env = null;
toplevel = null; toplevel = null;
endPositions = null; endPosTable = null;
nerrs = 0; nerrs = 0;
} }
} }

View file

@ -1,102 +0,0 @@
/*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.parser;
import java.util.Map;
import java.util.HashMap;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeInfo;
import static com.sun.tools.javac.tree.JCTree.*;
/**
* This class is similar to Parser except that it stores ending
* positions for the tree nodes.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b></p>
*/
public class EndPosParser extends JavacParser {
public EndPosParser(ParserFactory fac, Lexer S, boolean keepDocComments, boolean keepLineMap) {
super(fac, S, keepDocComments, keepLineMap);
this.S = S;
endPositions = new HashMap<JCTree,Integer>();
}
private Lexer S;
/** A hashtable to store ending positions
* of source ranges indexed by the tree nodes.
* Defined only if option flag genEndPos is set.
*/
Map<JCTree, Integer> endPositions;
/** {@inheritDoc} */
@Override
protected void storeEnd(JCTree tree, int endpos) {
int errorEndPos = getErrorEndPos();
endPositions.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
}
/** {@inheritDoc} */
@Override
protected <T extends JCTree> T to(T t) {
storeEnd(t, token.endPos);
return t;
}
/** {@inheritDoc} */
@Override
protected <T extends JCTree> T toP(T t) {
storeEnd(t, S.prevToken().endPos);
return t;
}
@Override
public JCCompilationUnit parseCompilationUnit() {
JCCompilationUnit t = super.parseCompilationUnit();
t.endPositions = endPositions;
return t;
}
/** {@inheritDoc} */
@Override
JCExpression parExpression() {
int pos = token.pos;
JCExpression t = super.parExpression();
return toP(F.at(pos).Parens(t));
}
/** {@inheritDoc} */
@Override
public int getEndPos(JCTree tree) {
return TreeInfo.getEndPos(tree, endPositions);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.parser;
import com.sun.tools.javac.tree.JCTree;
/**
* Specifies the methods to access a mappings of syntax trees to end positions.
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public interface EndPosTable {
/**
* This method will return the end position of a given tree, otherwise a
* Positions.NOPOS will be returned.
* @param tree JCTree
* @return position of the source tree or Positions.NOPOS for non-existent mapping
*/
public int getEndPos(JCTree tree);
/**
* Give an old tree and a new tree, the old tree will be replaced with
* the new tree, the position of the new tree will be that of the old
* tree.
* not exist.
* @param oldtree a JCTree to be replaced
* @param newtree a JCTree to be replaced with
* @return position of the old tree or Positions.NOPOS for non-existent mapping
*/
public int replaceTree(JCTree oldtree, JCTree newtree);
}

View file

@ -83,12 +83,16 @@ public class JavacParser implements Parser {
/** The name table. */ /** The name table. */
private Names names; private Names names;
/** End position mappings container */
private final AbstractEndPosTable endPosTable;
/** Construct a parser from a given scanner, tree factory and log. /** Construct a parser from a given scanner, tree factory and log.
*/ */
protected JavacParser(ParserFactory fac, protected JavacParser(ParserFactory fac,
Lexer S, Lexer S,
boolean keepDocComments, boolean keepDocComments,
boolean keepLineMap) { boolean keepLineMap,
boolean keepEndPositions) {
this.S = S; this.S = S;
nextToken(); // prime the pump nextToken(); // prime the pump
this.F = fac.F; this.F = fac.F;
@ -110,8 +114,14 @@ public class JavacParser implements Parser {
docComments = keepDocComments ? new HashMap<JCTree,String>() : null; docComments = keepDocComments ? new HashMap<JCTree,String>() : null;
this.keepLineMap = keepLineMap; this.keepLineMap = keepLineMap;
this.errorTree = F.Erroneous(); this.errorTree = F.Erroneous();
endPosTable = newEndPosTable(keepEndPositions);
} }
protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
return keepEndPositions
? new SimpleEndPosTable()
: new EmptyEndPosTable();
}
/** Switch: Should generics be recognized? /** Switch: Should generics be recognized?
*/ */
boolean allowGenerics; boolean allowGenerics;
@ -389,37 +399,21 @@ public class JavacParser implements Parser {
/* -------- source positions ------- */ /* -------- source positions ------- */
private int errorEndPos = -1;
private void setErrorEndPos(int errPos) { private void setErrorEndPos(int errPos) {
if (errPos > errorEndPos) endPosTable.setErrorEndPos(errPos);
errorEndPos = errPos;
} }
protected int getErrorEndPos() { private void storeEnd(JCTree tree, int endpos) {
return errorEndPos; endPosTable.storeEnd(tree, endpos);
} }
/** private <T extends JCTree> T to(T t) {
* Store ending position for a tree. return endPosTable.to(t);
* @param tree The tree. }
* @param endpos The ending position to associate with the tree.
*/
protected void storeEnd(JCTree tree, int endpos) {}
/** private <T extends JCTree> T toP(T t) {
* Store ending position for a tree. The ending position should return endPosTable.toP(t);
* be the ending position of the current token. }
* @param t The tree.
*/
protected <T extends JCTree> T to(T t) { return t; }
/**
* Store ending position for a tree. The ending position should
* be greater of the ending position of the previous token and errorEndPos.
* @param t The tree.
*/
protected <T extends JCTree> T toP(T t) { return t; }
/** Get the start position for a tree node. The start position is /** Get the start position for a tree node. The start position is
* defined to be the position of the first character of the first * defined to be the position of the first character of the first
@ -439,7 +433,7 @@ public class JavacParser implements Parser {
* @param tree The tree node * @param tree The tree node
*/ */
public int getEndPos(JCTree tree) { public int getEndPos(JCTree tree) {
return Position.NOPOS; return endPosTable.getEndPos(tree);
} }
@ -1362,7 +1356,7 @@ public class JavacParser implements Parser {
int pos = token.pos; int pos = token.pos;
nextToken(); nextToken();
accept(CLASS); accept(CLASS);
if (token.pos == errorEndPos) { if (token.pos == endPosTable.errorEndPos) {
// error recovery // error recovery
Name name = null; Name name = null;
if (token.kind == IDENTIFIER) { if (token.kind == IDENTIFIER) {
@ -1542,10 +1536,11 @@ public class JavacParser implements Parser {
/** ParExpression = "(" Expression ")" /** ParExpression = "(" Expression ")"
*/ */
JCExpression parExpression() { JCExpression parExpression() {
int pos = token.pos;
accept(LPAREN); accept(LPAREN);
JCExpression t = parseExpression(); JCExpression t = parseExpression();
accept(RPAREN); accept(RPAREN);
return t; return toP(F.at(pos).Parens(t));
} }
/** Block = "{" BlockStatements "}" /** Block = "{" BlockStatements "}"
@ -1661,7 +1656,7 @@ public class JavacParser implements Parser {
// error recovery // error recovery
if (token.pos == lastErrPos) if (token.pos == lastErrPos)
return stats.toList(); return stats.toList();
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
skip(false, true, true, true); skip(false, true, true, true);
lastErrPos = token.pos; lastErrPos = token.pos;
} }
@ -2270,7 +2265,7 @@ public class JavacParser implements Parser {
boolean checkForImports = true; boolean checkForImports = true;
boolean firstTypeDecl = true; boolean firstTypeDecl = true;
while (token.kind != EOF) { while (token.kind != EOF) {
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(checkForImports, false, false, false); skip(checkForImports, false, false, false);
if (token.kind == EOF) if (token.kind == EOF)
@ -2304,6 +2299,7 @@ public class JavacParser implements Parser {
toplevel.docComments = docComments; toplevel.docComments = docComments;
if (keepLineMap) if (keepLineMap)
toplevel.lineMap = S.getLineMap(); toplevel.lineMap = S.getLineMap();
toplevel.endPositions = this.endPosTable;
return toplevel; return toplevel;
} }
@ -2494,7 +2490,7 @@ public class JavacParser implements Parser {
while (token.kind != RBRACE && token.kind != EOF) { while (token.kind != RBRACE && token.kind != EOF) {
defs.appendList(classOrInterfaceBodyDeclaration(enumName, defs.appendList(classOrInterfaceBodyDeclaration(enumName,
false)); false));
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, true, false); skip(false, true, true, false);
} }
@ -2556,7 +2552,7 @@ public class JavacParser implements Parser {
*/ */
List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
accept(LBRACE); accept(LBRACE);
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, false, false); skip(false, true, false, false);
if (token.kind == LBRACE) if (token.kind == LBRACE)
@ -2565,7 +2561,7 @@ public class JavacParser implements Parser {
ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
while (token.kind != RBRACE && token.kind != EOF) { while (token.kind != RBRACE && token.kind != EOF) {
defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, true, false); skip(false, true, true, false);
} }
@ -2697,7 +2693,7 @@ public class JavacParser implements Parser {
defaultValue = null; defaultValue = null;
} }
accept(SEMI); accept(SEMI);
if (token.pos <= errorEndPos) { if (token.pos <= endPosTable.errorEndPos) {
// error recovery // error recovery
skip(false, true, false, false); skip(false, true, false, false);
if (token.kind == LBRACE) { if (token.kind == LBRACE) {
@ -3028,4 +3024,112 @@ public class JavacParser implements Parser {
allowTWR = true; allowTWR = true;
} }
} }
/*
* a functional source tree and end position mappings
*/
protected class SimpleEndPosTable extends AbstractEndPosTable {
private final Map<JCTree, Integer> endPosMap;
SimpleEndPosTable() {
endPosMap = new HashMap<JCTree, Integer>();
}
protected void storeEnd(JCTree tree, int endpos) {
endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
}
protected <T extends JCTree> T to(T t) {
storeEnd(t, token.endPos);
return t;
}
protected <T extends JCTree> T toP(T t) {
storeEnd(t, S.prevToken().endPos);
return t;
}
public int getEndPos(JCTree tree) {
Integer value = endPosMap.get(tree);
return (value == null) ? Position.NOPOS : value;
}
public int replaceTree(JCTree oldTree, JCTree newTree) {
Integer pos = endPosMap.remove(oldTree);
if (pos != null) {
endPosMap.put(newTree, pos);
return pos;
}
return Position.NOPOS;
}
}
/*
* a default skeletal implementation without any mapping overhead.
*/
protected class EmptyEndPosTable extends AbstractEndPosTable {
protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
protected <T extends JCTree> T to(T t) {
return t;
}
protected <T extends JCTree> T toP(T t) {
return t;
}
public int getEndPos(JCTree tree) {
return Position.NOPOS;
}
public int replaceTree(JCTree oldTree, JCTree newTree) {
return Position.NOPOS;
}
}
protected abstract class AbstractEndPosTable implements EndPosTable {
/**
* Store the last error position.
*/
protected int errorEndPos;
/**
* Store ending position for a tree, the value of which is the greater
* of last error position and the given ending position.
* @param tree The tree.
* @param endpos The ending position to associate with the tree.
*/
protected abstract void storeEnd(JCTree tree, int endpos);
/**
* Store current token's ending position for a tree, the value of which
* will be the greater of last error position and the ending position of
* the current token.
* @param t The tree.
*/
protected abstract <T extends JCTree> T to(T t);
/**
* Store current token's ending position for a tree, the value of which
* will be the greater of last error position and the ending position of
* the previous token.
* @param t The tree.
*/
protected abstract <T extends JCTree> T toP(T t);
/**
* Set the error position during the parsing phases, the value of which
* will be set only if it is greater than the last stored error position.
* @param errPos The error position
*/
protected void setErrorEndPos(int errPos) {
if (errPos > errorEndPos) {
errorEndPos = errPos;
}
}
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -75,10 +75,6 @@ public class ParserFactory {
public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
Lexer lexer = scannerFactory.newScanner(input, keepDocComments); Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
if (keepEndPos) { return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
} else {
return new JavacParser(this, lexer, keepDocComments, keepLineMap);
}
} }
} }

View file

@ -39,6 +39,7 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.*; import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.source.tree.*; import com.sun.source.tree.*;
import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.BoundKind.*;
@ -450,7 +451,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
} }
// for default DiagnosticPosition // for default DiagnosticPosition
public int getEndPosition(Map<JCTree, Integer> endPosTable) { public int getEndPosition(EndPosTable endPosTable) {
return TreeInfo.getEndPos(this, endPosTable); return TreeInfo.getEndPos(this, endPosTable);
} }
@ -467,7 +468,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
* @param docComments A hashtable that stores all documentation comments * @param docComments A hashtable that stores all documentation comments
* indexed by the tree nodes they refer to. * indexed by the tree nodes they refer to.
* defined only if option -s is set. * defined only if option -s is set.
* @param endPositions A hashtable that stores ending positions of source * @param endPositions An object encapsulating ending positions of source
* ranges indexed by the tree nodes they belong to. * ranges indexed by the tree nodes they belong to.
* Defined only if option -Xjcov is set. * Defined only if option -Xjcov is set.
*/ */
@ -481,7 +482,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public StarImportScope starImportScope; public StarImportScope starImportScope;
public Position.LineMap lineMap = null; public Position.LineMap lineMap = null;
public Map<JCTree, String> docComments = null; public Map<JCTree, String> docComments = null;
public Map<JCTree, Integer> endPositions = null; public EndPosTable endPositions = null;
protected JCCompilationUnit(List<JCAnnotation> packageAnnotations, protected JCCompilationUnit(List<JCAnnotation> packageAnnotations,
JCExpression pid, JCExpression pid,
List<JCTree> defs, List<JCTree> defs,

View file

@ -28,10 +28,10 @@ package com.sun.tools.javac.tree;
import com.sun.source.tree.Tree; import com.sun.source.tree.Tree;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
import java.util.Map;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
@ -346,17 +346,17 @@ public class TreeInfo {
/** The end position of given tree, given a table of end positions generated by the parser /** The end position of given tree, given a table of end positions generated by the parser
*/ */
public static int getEndPos(JCTree tree, Map<JCTree, Integer> endPositions) { public static int getEndPos(JCTree tree, EndPosTable endPosTable) {
if (tree == null) if (tree == null)
return Position.NOPOS; return Position.NOPOS;
if (endPositions == null) { if (endPosTable == null) {
// fall back on limited info in the tree // fall back on limited info in the tree
return endPos(tree); return endPos(tree);
} }
Integer mapPos = endPositions.get(tree); int mapPos = endPosTable.getEndPos(tree);
if (mapPos != null) if (mapPos != Position.NOPOS)
return mapPos; return mapPos;
switch(tree.getTag()) { switch(tree.getTag()) {
@ -364,7 +364,7 @@ public class TreeInfo {
case SL_ASG: case SR_ASG: case USR_ASG: case SL_ASG: case SR_ASG: case USR_ASG:
case PLUS_ASG: case MINUS_ASG: case MUL_ASG: case PLUS_ASG: case MINUS_ASG: case MUL_ASG:
case DIV_ASG: case MOD_ASG: case DIV_ASG: case MOD_ASG:
return getEndPos(((JCAssignOp) tree).rhs, endPositions); return getEndPos(((JCAssignOp) tree).rhs, endPosTable);
case OR: case AND: case BITOR: case OR: case AND: case BITOR:
case BITXOR: case BITAND: case EQ: case BITXOR: case BITAND: case EQ:
case NE: case LT: case GT: case NE: case LT: case GT:
@ -372,62 +372,62 @@ public class TreeInfo {
case SR: case USR: case PLUS: case SR: case USR: case PLUS:
case MINUS: case MUL: case DIV: case MINUS: case MUL: case DIV:
case MOD: case MOD:
return getEndPos(((JCBinary) tree).rhs, endPositions); return getEndPos(((JCBinary) tree).rhs, endPosTable);
case CASE: case CASE:
return getEndPos(((JCCase) tree).stats.last(), endPositions); return getEndPos(((JCCase) tree).stats.last(), endPosTable);
case CATCH: case CATCH:
return getEndPos(((JCCatch) tree).body, endPositions); return getEndPos(((JCCatch) tree).body, endPosTable);
case CONDEXPR: case CONDEXPR:
return getEndPos(((JCConditional) tree).falsepart, endPositions); return getEndPos(((JCConditional) tree).falsepart, endPosTable);
case FORLOOP: case FORLOOP:
return getEndPos(((JCForLoop) tree).body, endPositions); return getEndPos(((JCForLoop) tree).body, endPosTable);
case FOREACHLOOP: case FOREACHLOOP:
return getEndPos(((JCEnhancedForLoop) tree).body, endPositions); return getEndPos(((JCEnhancedForLoop) tree).body, endPosTable);
case IF: { case IF: {
JCIf node = (JCIf)tree; JCIf node = (JCIf)tree;
if (node.elsepart == null) { if (node.elsepart == null) {
return getEndPos(node.thenpart, endPositions); return getEndPos(node.thenpart, endPosTable);
} else { } else {
return getEndPos(node.elsepart, endPositions); return getEndPos(node.elsepart, endPosTable);
} }
} }
case LABELLED: case LABELLED:
return getEndPos(((JCLabeledStatement) tree).body, endPositions); return getEndPos(((JCLabeledStatement) tree).body, endPosTable);
case MODIFIERS: case MODIFIERS:
return getEndPos(((JCModifiers) tree).annotations.last(), endPositions); return getEndPos(((JCModifiers) tree).annotations.last(), endPosTable);
case SYNCHRONIZED: case SYNCHRONIZED:
return getEndPos(((JCSynchronized) tree).body, endPositions); return getEndPos(((JCSynchronized) tree).body, endPosTable);
case TOPLEVEL: case TOPLEVEL:
return getEndPos(((JCCompilationUnit) tree).defs.last(), endPositions); return getEndPos(((JCCompilationUnit) tree).defs.last(), endPosTable);
case TRY: { case TRY: {
JCTry node = (JCTry)tree; JCTry node = (JCTry)tree;
if (node.finalizer != null) { if (node.finalizer != null) {
return getEndPos(node.finalizer, endPositions); return getEndPos(node.finalizer, endPosTable);
} else if (!node.catchers.isEmpty()) { } else if (!node.catchers.isEmpty()) {
return getEndPos(node.catchers.last(), endPositions); return getEndPos(node.catchers.last(), endPosTable);
} else { } else {
return getEndPos(node.body, endPositions); return getEndPos(node.body, endPosTable);
} }
} }
case WILDCARD: case WILDCARD:
return getEndPos(((JCWildcard) tree).inner, endPositions); return getEndPos(((JCWildcard) tree).inner, endPosTable);
case TYPECAST: case TYPECAST:
return getEndPos(((JCTypeCast) tree).expr, endPositions); return getEndPos(((JCTypeCast) tree).expr, endPosTable);
case TYPETEST: case TYPETEST:
return getEndPos(((JCInstanceOf) tree).clazz, endPositions); return getEndPos(((JCInstanceOf) tree).clazz, endPosTable);
case POS: case POS:
case NEG: case NEG:
case NOT: case NOT:
case COMPL: case COMPL:
case PREINC: case PREINC:
case PREDEC: case PREDEC:
return getEndPos(((JCUnary) tree).arg, endPositions); return getEndPos(((JCUnary) tree).arg, endPosTable);
case WHILELOOP: case WHILELOOP:
return getEndPos(((JCWhileLoop) tree).body, endPositions); return getEndPos(((JCWhileLoop) tree).body, endPosTable);
case ERRONEOUS: { case ERRONEOUS: {
JCErroneous node = (JCErroneous)tree; JCErroneous node = (JCErroneous)tree;
if (node.errs != null && node.errs.nonEmpty()) if (node.errs != null && node.errs.nonEmpty())
return getEndPos(node.errs.last(), endPositions); return getEndPos(node.errs.last(), endPosTable);
} }
} }
return Position.NOPOS; return Position.NOPOS;
@ -444,7 +444,7 @@ public class TreeInfo {
public JCTree getTree() { return tree; } public JCTree getTree() { return tree; }
public int getStartPosition() { return TreeInfo.getStartPos(tree); } public int getStartPosition() { return TreeInfo.getStartPos(tree); }
public int getPreferredPosition() { return endPos; } public int getPreferredPosition() { return endPos; }
public int getEndPosition(Map<JCTree, Integer> endPosTable) { public int getEndPosition(EndPosTable endPosTable) {
return TreeInfo.getEndPos(tree, endPosTable); return TreeInfo.getEndPos(tree, endPosTable);
} }
}; };

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ import java.util.Map;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import static com.sun.tools.javac.util.LayoutCharacters.*; import static com.sun.tools.javac.util.LayoutCharacters.*;
@ -128,11 +129,11 @@ public class DiagnosticSource {
} }
} }
public Map<JCTree, Integer> getEndPosTable() { public EndPosTable getEndPosTable() {
return endPosTable; return endPosTable;
} }
public void setEndPosTable(Map<JCTree, Integer> t) { public void setEndPosTable(EndPosTable t) {
if (endPosTable != null && endPosTable != t) if (endPosTable != null && endPosTable != t)
throw new IllegalStateException("endPosTable already set"); throw new IllegalStateException("endPosTable already set");
endPosTable = t; endPosTable = t;
@ -199,7 +200,7 @@ public class DiagnosticSource {
/** The underlying file object. */ /** The underlying file object. */
protected JavaFileObject fileObject; protected JavaFileObject fileObject;
protected Map<JCTree, Integer> endPosTable; protected EndPosTable endPosTable;
/** A soft reference to the content of the file object. */ /** A soft reference to the content of the file object. */
protected SoftReference<char[]> refBuf; protected SoftReference<char[]> refBuf;

View file

@ -35,6 +35,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter; import com.sun.tools.javac.api.DiagnosticFormatter;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
@ -313,7 +314,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
/** If there is a tree node, and if endPositions are available, get /** If there is a tree node, and if endPositions are available, get
* the end position of the tree node. Otherwise, just returns the * the end position of the tree node. Otherwise, just returns the
* same as getPreferredPosition(). */ * same as getPreferredPosition(). */
int getEndPosition(Map<JCTree, Integer> endPosTable); int getEndPosition(EndPosTable endPosTable);
} }
/** /**
@ -337,7 +338,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
return pos; return pos;
} }
public int getEndPosition(Map<JCTree, Integer> endPosTable) { public int getEndPosition(EndPosTable endPosTable) {
return pos; return pos;
} }

View file

@ -38,6 +38,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter; import com.sun.tools.javac.api.DiagnosticFormatter;
import com.sun.tools.javac.main.OptionName; import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
@ -250,9 +251,9 @@ public class Log extends AbstractLog {
return diagListener != null; return diagListener != null;
} }
public void setEndPosTable(JavaFileObject name, Map<JCTree, Integer> table) { public void setEndPosTable(JavaFileObject name, EndPosTable endPosTable) {
name.getClass(); // null check name.getClass(); // null check
getSource(name).setEndPosTable(table); getSource(name).setEndPosTable(endPosTable);
} }
/** Return current sourcefile. /** Return current sourcefile.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import java.net.URI;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.parser.Parser; import com.sun.tools.javac.parser.Parser;
import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
@ -97,9 +98,9 @@ public class TestLog
} }
private static class LogTester extends TreeScanner { private static class LogTester extends TreeScanner {
LogTester(Log log, java.util.Map<JCTree, Integer> endPositions) { LogTester(Log log, EndPosTable endPosTable) {
this.log = log; this.log = log;
this.endPositions = endPositions; this.endPosTable = endPosTable;
} }
public void visitIf(JCTree.JCIf tree) { public void visitIf(JCTree.JCIf tree) {
@ -117,7 +118,7 @@ public class TestLog
} }
private Log log; private Log log;
private java.util.Map<JCTree, Integer> endPositions; private EndPosTable endPosTable;
} }
private static class StringJavaFileObject extends SimpleJavaFileObject { private static class StringJavaFileObject extends SimpleJavaFileObject {

View file

@ -55,12 +55,8 @@ import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener; import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -72,8 +68,8 @@ import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeInfo;
@ -421,7 +417,7 @@ public class CheckAttributedTree {
} }
JavaFileObject sourcefile; JavaFileObject sourcefile;
Map<JCTree, Integer> endPosTable; EndPosTable endPosTable;
Info encl; Info encl;
} }
@ -437,7 +433,7 @@ public class CheckAttributedTree {
end = Integer.MAX_VALUE; end = Integer.MAX_VALUE;
} }
Info(JCTree tree, Map<JCTree, Integer> endPosTable) { Info(JCTree tree, EndPosTable endPosTable) {
this.tree = tree; this.tree = tree;
tag = tree.getTag(); tag = tree.getTag();
start = TreeInfo.getStartPos(tree); start = TreeInfo.getStartPos(tree);

View file

@ -73,6 +73,7 @@ import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.parser.EndPosTable;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCNewClass;
@ -435,7 +436,7 @@ public class TreePosTest {
} }
JavaFileObject sourcefile; JavaFileObject sourcefile;
Map<JCTree, Integer> endPosTable; EndPosTable endPosTable;
Info encl; Info encl;
} }
@ -452,7 +453,7 @@ public class TreePosTest {
end = Integer.MAX_VALUE; end = Integer.MAX_VALUE;
} }
Info(JCTree tree, Map<JCTree, Integer> endPosTable) { Info(JCTree tree, EndPosTable endPosTable) {
this.tree = tree; this.tree = tree;
tag = tree.getTag(); tag = tree.getTag();
start = TreeInfo.getStartPos(tree); start = TreeInfo.getStartPos(tree);