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