src/share/classes/com/sun/tools/javac/parser/JavacParser.java

changeset 1138
7375d4979bd3
parent 1127
ca49d50318dc
child 1144
9448fe783fd2
equal deleted inserted replaced
1137:c1238fcc9515 1138:7375d4979bd3
81 private Source source; 81 private Source source;
82 82
83 /** The name table. */ 83 /** The name table. */
84 private Names names; 84 private Names names;
85 85
86 /** End position mappings container */
87 private final AbstractEndPosTable endPosTable;
88
86 /** Construct a parser from a given scanner, tree factory and log. 89 /** Construct a parser from a given scanner, tree factory and log.
87 */ 90 */
88 protected JavacParser(ParserFactory fac, 91 protected JavacParser(ParserFactory fac,
89 Lexer S, 92 Lexer S,
90 boolean keepDocComments, 93 boolean keepDocComments,
91 boolean keepLineMap) { 94 boolean keepLineMap,
95 boolean keepEndPositions) {
92 this.S = S; 96 this.S = S;
93 nextToken(); // prime the pump 97 nextToken(); // prime the pump
94 this.F = fac.F; 98 this.F = fac.F;
95 this.log = fac.log; 99 this.log = fac.log;
96 this.names = fac.names; 100 this.names = fac.names;
108 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); 112 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
109 this.keepDocComments = keepDocComments; 113 this.keepDocComments = keepDocComments;
110 docComments = keepDocComments ? new HashMap<JCTree,String>() : null; 114 docComments = keepDocComments ? new HashMap<JCTree,String>() : null;
111 this.keepLineMap = keepLineMap; 115 this.keepLineMap = keepLineMap;
112 this.errorTree = F.Erroneous(); 116 this.errorTree = F.Erroneous();
113 } 117 endPosTable = newEndPosTable(keepEndPositions);
114 118 }
119
120 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
121 return keepEndPositions
122 ? new SimpleEndPosTable()
123 : new EmptyEndPosTable();
124 }
115 /** Switch: Should generics be recognized? 125 /** Switch: Should generics be recognized?
116 */ 126 */
117 boolean allowGenerics; 127 boolean allowGenerics;
118 128
119 /** Switch: Should diamond operator be recognized? 129 /** Switch: Should diamond operator be recognized?
387 } 397 }
388 } 398 }
389 399
390 /* -------- source positions ------- */ 400 /* -------- source positions ------- */
391 401
392 private int errorEndPos = -1;
393
394 private void setErrorEndPos(int errPos) { 402 private void setErrorEndPos(int errPos) {
395 if (errPos > errorEndPos) 403 endPosTable.setErrorEndPos(errPos);
396 errorEndPos = errPos; 404 }
397 } 405
398 406 private void storeEnd(JCTree tree, int endpos) {
399 protected int getErrorEndPos() { 407 endPosTable.storeEnd(tree, endpos);
400 return errorEndPos; 408 }
401 } 409
402 410 private <T extends JCTree> T to(T t) {
403 /** 411 return endPosTable.to(t);
404 * Store ending position for a tree. 412 }
405 * @param tree The tree. 413
406 * @param endpos The ending position to associate with the tree. 414 private <T extends JCTree> T toP(T t) {
407 */ 415 return endPosTable.toP(t);
408 protected void storeEnd(JCTree tree, int endpos) {} 416 }
409
410 /**
411 * Store ending position for a tree. The ending position should
412 * be the ending position of the current token.
413 * @param t The tree.
414 */
415 protected <T extends JCTree> T to(T t) { return t; }
416
417 /**
418 * Store ending position for a tree. The ending position should
419 * be greater of the ending position of the previous token and errorEndPos.
420 * @param t The tree.
421 */
422 protected <T extends JCTree> T toP(T t) { return t; }
423 417
424 /** Get the start position for a tree node. The start position is 418 /** Get the start position for a tree node. The start position is
425 * defined to be the position of the first character of the first 419 * defined to be the position of the first character of the first
426 * token of the node's source text. 420 * token of the node's source text.
427 * @param tree The tree node 421 * @param tree The tree node
437 * positions are not generated or the position is otherwise not 431 * positions are not generated or the position is otherwise not
438 * found. 432 * found.
439 * @param tree The tree node 433 * @param tree The tree node
440 */ 434 */
441 public int getEndPos(JCTree tree) { 435 public int getEndPos(JCTree tree) {
442 return Position.NOPOS; 436 return endPosTable.getEndPos(tree);
443 } 437 }
444 438
445 439
446 440
447 /* ---------- parsing -------------- */ 441 /* ---------- parsing -------------- */
1360 if ((mode & EXPR) != 0 && token.kind == DOT) { 1354 if ((mode & EXPR) != 0 && token.kind == DOT) {
1361 mode = EXPR; 1355 mode = EXPR;
1362 int pos = token.pos; 1356 int pos = token.pos;
1363 nextToken(); 1357 nextToken();
1364 accept(CLASS); 1358 accept(CLASS);
1365 if (token.pos == errorEndPos) { 1359 if (token.pos == endPosTable.errorEndPos) {
1366 // error recovery 1360 // error recovery
1367 Name name = null; 1361 Name name = null;
1368 if (token.kind == IDENTIFIER) { 1362 if (token.kind == IDENTIFIER) {
1369 name = token.name(); 1363 name = token.name();
1370 nextToken(); 1364 nextToken();
1540 } 1534 }
1541 1535
1542 /** ParExpression = "(" Expression ")" 1536 /** ParExpression = "(" Expression ")"
1543 */ 1537 */
1544 JCExpression parExpression() { 1538 JCExpression parExpression() {
1539 int pos = token.pos;
1545 accept(LPAREN); 1540 accept(LPAREN);
1546 JCExpression t = parseExpression(); 1541 JCExpression t = parseExpression();
1547 accept(RPAREN); 1542 accept(RPAREN);
1548 return t; 1543 return toP(F.at(pos).Parens(t));
1549 } 1544 }
1550 1545
1551 /** Block = "{" BlockStatements "}" 1546 /** Block = "{" BlockStatements "}"
1552 */ 1547 */
1553 JCBlock block(int pos, long flags) { 1548 JCBlock block(int pos, long flags) {
1659 } 1654 }
1660 1655
1661 // error recovery 1656 // error recovery
1662 if (token.pos == lastErrPos) 1657 if (token.pos == lastErrPos)
1663 return stats.toList(); 1658 return stats.toList();
1664 if (token.pos <= errorEndPos) { 1659 if (token.pos <= endPosTable.errorEndPos) {
1665 skip(false, true, true, true); 1660 skip(false, true, true, true);
1666 lastErrPos = token.pos; 1661 lastErrPos = token.pos;
1667 } 1662 }
1668 } 1663 }
1669 } 1664 }
2268 } 2263 }
2269 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2264 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2270 boolean checkForImports = true; 2265 boolean checkForImports = true;
2271 boolean firstTypeDecl = true; 2266 boolean firstTypeDecl = true;
2272 while (token.kind != EOF) { 2267 while (token.kind != EOF) {
2273 if (token.pos <= errorEndPos) { 2268 if (token.pos <= endPosTable.errorEndPos) {
2274 // error recovery 2269 // error recovery
2275 skip(checkForImports, false, false, false); 2270 skip(checkForImports, false, false, false);
2276 if (token.kind == EOF) 2271 if (token.kind == EOF)
2277 break; 2272 break;
2278 } 2273 }
2302 storeEnd(toplevel, S.prevToken().endPos); 2297 storeEnd(toplevel, S.prevToken().endPos);
2303 if (keepDocComments) 2298 if (keepDocComments)
2304 toplevel.docComments = docComments; 2299 toplevel.docComments = docComments;
2305 if (keepLineMap) 2300 if (keepLineMap)
2306 toplevel.lineMap = S.getLineMap(); 2301 toplevel.lineMap = S.getLineMap();
2302 toplevel.endPositions = this.endPosTable;
2307 return toplevel; 2303 return toplevel;
2308 } 2304 }
2309 2305
2310 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 2306 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2311 */ 2307 */
2492 if (token.kind == SEMI) { 2488 if (token.kind == SEMI) {
2493 nextToken(); 2489 nextToken();
2494 while (token.kind != RBRACE && token.kind != EOF) { 2490 while (token.kind != RBRACE && token.kind != EOF) {
2495 defs.appendList(classOrInterfaceBodyDeclaration(enumName, 2491 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
2496 false)); 2492 false));
2497 if (token.pos <= errorEndPos) { 2493 if (token.pos <= endPosTable.errorEndPos) {
2498 // error recovery 2494 // error recovery
2499 skip(false, true, true, false); 2495 skip(false, true, true, false);
2500 } 2496 }
2501 } 2497 }
2502 } 2498 }
2554 /** ClassBody = "{" {ClassBodyDeclaration} "}" 2550 /** ClassBody = "{" {ClassBodyDeclaration} "}"
2555 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 2551 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2556 */ 2552 */
2557 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 2553 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
2558 accept(LBRACE); 2554 accept(LBRACE);
2559 if (token.pos <= errorEndPos) { 2555 if (token.pos <= endPosTable.errorEndPos) {
2560 // error recovery 2556 // error recovery
2561 skip(false, true, false, false); 2557 skip(false, true, false, false);
2562 if (token.kind == LBRACE) 2558 if (token.kind == LBRACE)
2563 nextToken(); 2559 nextToken();
2564 } 2560 }
2565 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2561 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2566 while (token.kind != RBRACE && token.kind != EOF) { 2562 while (token.kind != RBRACE && token.kind != EOF) {
2567 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 2563 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
2568 if (token.pos <= errorEndPos) { 2564 if (token.pos <= endPosTable.errorEndPos) {
2569 // error recovery 2565 // error recovery
2570 skip(false, true, true, false); 2566 skip(false, true, true, false);
2571 } 2567 }
2572 } 2568 }
2573 accept(RBRACE); 2569 accept(RBRACE);
2695 defaultValue = annotationValue(); 2691 defaultValue = annotationValue();
2696 } else { 2692 } else {
2697 defaultValue = null; 2693 defaultValue = null;
2698 } 2694 }
2699 accept(SEMI); 2695 accept(SEMI);
2700 if (token.pos <= errorEndPos) { 2696 if (token.pos <= endPosTable.errorEndPos) {
2701 // error recovery 2697 // error recovery
2702 skip(false, true, false, false); 2698 skip(false, true, false, false);
2703 if (token.kind == LBRACE) { 2699 if (token.kind == LBRACE) {
2704 body = block(); 2700 body = block();
2705 } 2701 }
3026 if (!allowTWR) { 3022 if (!allowTWR) {
3027 error(token.pos, "try.with.resources.not.supported.in.source", source.name); 3023 error(token.pos, "try.with.resources.not.supported.in.source", source.name);
3028 allowTWR = true; 3024 allowTWR = true;
3029 } 3025 }
3030 } 3026 }
3027
3028 /*
3029 * a functional source tree and end position mappings
3030 */
3031 protected class SimpleEndPosTable extends AbstractEndPosTable {
3032
3033 private final Map<JCTree, Integer> endPosMap;
3034
3035 SimpleEndPosTable() {
3036 endPosMap = new HashMap<JCTree, Integer>();
3037 }
3038
3039 protected void storeEnd(JCTree tree, int endpos) {
3040 endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
3041 }
3042
3043 protected <T extends JCTree> T to(T t) {
3044 storeEnd(t, token.endPos);
3045 return t;
3046 }
3047
3048 protected <T extends JCTree> T toP(T t) {
3049 storeEnd(t, S.prevToken().endPos);
3050 return t;
3051 }
3052
3053 public int getEndPos(JCTree tree) {
3054 Integer value = endPosMap.get(tree);
3055 return (value == null) ? Position.NOPOS : value;
3056 }
3057
3058 public int replaceTree(JCTree oldTree, JCTree newTree) {
3059 Integer pos = endPosMap.remove(oldTree);
3060 if (pos != null) {
3061 endPosMap.put(newTree, pos);
3062 return pos;
3063 }
3064 return Position.NOPOS;
3065 }
3066 }
3067
3068 /*
3069 * a default skeletal implementation without any mapping overhead.
3070 */
3071 protected class EmptyEndPosTable extends AbstractEndPosTable {
3072
3073 protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
3074
3075 protected <T extends JCTree> T to(T t) {
3076 return t;
3077 }
3078
3079 protected <T extends JCTree> T toP(T t) {
3080 return t;
3081 }
3082
3083 public int getEndPos(JCTree tree) {
3084 return Position.NOPOS;
3085 }
3086
3087 public int replaceTree(JCTree oldTree, JCTree newTree) {
3088 return Position.NOPOS;
3089 }
3090
3091 }
3092
3093 protected abstract class AbstractEndPosTable implements EndPosTable {
3094
3095 /**
3096 * Store the last error position.
3097 */
3098 protected int errorEndPos;
3099
3100 /**
3101 * Store ending position for a tree, the value of which is the greater
3102 * of last error position and the given ending position.
3103 * @param tree The tree.
3104 * @param endpos The ending position to associate with the tree.
3105 */
3106 protected abstract void storeEnd(JCTree tree, int endpos);
3107
3108 /**
3109 * Store current token's ending position for a tree, the value of which
3110 * will be the greater of last error position and the ending position of
3111 * the current token.
3112 * @param t The tree.
3113 */
3114 protected abstract <T extends JCTree> T to(T t);
3115
3116 /**
3117 * Store current token's ending position for a tree, the value of which
3118 * will be the greater of last error position and the ending position of
3119 * the previous token.
3120 * @param t The tree.
3121 */
3122 protected abstract <T extends JCTree> T toP(T t);
3123
3124 /**
3125 * Set the error position during the parsing phases, the value of which
3126 * will be set only if it is greater than the last stored error position.
3127 * @param errPos The error position
3128 */
3129 protected void setErrorEndPos(int errPos) {
3130 if (errPos > errorEndPos) {
3131 errorEndPos = errPos;
3132 }
3133 }
3134 }
3031 } 3135 }

mercurial