114 /** Construct a parser from a given scanner, tree factory and log.
115 */
116 protected JavacParser(ParserFactory fac,
117 Lexer S,
118 boolean keepDocComments,
119 boolean keepLineMap) {
120 this.S = S;
121 S.nextToken(); // prime the pump
122 this.F = fac.F;
123 this.log = fac.log;
124 this.names = fac.names;
125 this.keywords = fac.keywords;
126 this.source = fac.source;
127 this.allowGenerics = source.allowGenerics();
128 this.allowVarargs = source.allowVarargs();
129 this.allowAsserts = source.allowAsserts();
130 this.allowEnums = source.allowEnums();
131 this.allowForeach = source.allowForeach();
132 this.allowStaticImport = source.allowStaticImport();
133 this.allowAnnotations = source.allowAnnotations();
134 this.allowDiamond = source.allowDiamond();
135 this.allowMulticatch = source.allowMulticatch();
136 this.allowTypeAnnotations = source.allowTypeAnnotations();
137 this.keepDocComments = keepDocComments;
138 if (keepDocComments)
139 docComments = new HashMap<JCTree,String>();
140 this.keepLineMap = keepLineMap;
141 this.errorTree = F.Erroneous();
142 this.debugJSR308 = fac.options.get("TA:parser") != null;
143 }
144
145 /** Switch: debug output for type-annotations operations
146 */
147 boolean debugJSR308;
148
149 /** Switch: Should generics be recognized?
150 */
151 boolean allowGenerics;
152
153 /** Switch: Should diamond operator be recognized?
169 /** Switch: should we recognize enums, or just give a warning?
170 */
171 boolean allowEnums;
172
173 /** Switch: should we recognize foreach?
174 */
175 boolean allowForeach;
176
177 /** Switch: should we recognize foreach?
178 */
179 boolean allowStaticImport;
180
181 /** Switch: should we recognize annotations?
182 */
183 boolean allowAnnotations;
184
185 /** Switch: should we recognize type annotations?
186 */
187 boolean allowTypeAnnotations;
188
189 /** Switch: should we keep docComments?
190 */
191 boolean keepDocComments;
192
193 /** Switch: should we keep line table?
194 */
195 boolean keepLineMap;
196
197 /** When terms are parsed, the mode determines which is expected:
198 * mode = EXPR : an expression
199 * mode = TYPE : a type
200 * mode = NOPARAMS : no parameters allowed for type
201 * mode = TYPEARG : type argument
202 */
203 static final int EXPR = 0x1;
204 static final int TYPE = 0x2;
205 static final int NOPARAMS = 0x4;
206 static final int TYPEARG = 0x8;
207 static final int DIAMOND = 0x10;
208
1825 if (S.pos() == lastErrPos)
1826 return stats.toList();
1827 if (S.pos() <= errorEndPos) {
1828 skip(false, true, true, true);
1829 lastErrPos = S.pos();
1830 }
1831
1832 // ensure no dangling /** @deprecated */ active
1833 S.resetDeprecatedFlag();
1834 }
1835 }
1836
1837 /** Statement =
1838 * Block
1839 * | IF ParExpression Statement [ELSE Statement]
1840 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1841 * | FOR "(" FormalParameter : Expression ")" Statement
1842 * | WHILE ParExpression Statement
1843 * | DO Statement WHILE ParExpression ";"
1844 * | TRY Block ( Catches | [Catches] FinallyPart )
1845 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1846 * | SYNCHRONIZED ParExpression Block
1847 * | RETURN [Expression] ";"
1848 * | THROW Expression ";"
1849 * | BREAK [Ident] ";"
1850 * | CONTINUE [Ident] ";"
1851 * | ASSERT Expression [ ":" Expression ] ";"
1852 * | ";"
1853 * | ExpressionStatement
1854 * | Ident ":" Statement
1855 */
1856 @SuppressWarnings("fallthrough")
1857 public JCStatement parseStatement() {
1858 int pos = S.pos();
1859 switch (S.token()) {
1860 case LBRACE:
1861 return block();
1862 case IF: {
1863 S.nextToken();
1864 JCExpression cond = parExpression();
1895 return F.at(pos).ForLoop(inits, cond, steps, body);
1896 }
1897 }
1898 case WHILE: {
1899 S.nextToken();
1900 JCExpression cond = parExpression();
1901 JCStatement body = parseStatement();
1902 return F.at(pos).WhileLoop(cond, body);
1903 }
1904 case DO: {
1905 S.nextToken();
1906 JCStatement body = parseStatement();
1907 accept(WHILE);
1908 JCExpression cond = parExpression();
1909 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1910 accept(SEMI);
1911 return t;
1912 }
1913 case TRY: {
1914 S.nextToken();
1915 JCBlock body = block();
1916 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1917 JCBlock finalizer = null;
1918 if (S.token() == CATCH || S.token() == FINALLY) {
1919 while (S.token() == CATCH) catchers.append(catchClause());
1920 if (S.token() == FINALLY) {
1921 S.nextToken();
1922 finalizer = block();
1923 }
1924 } else {
1925 log.error(pos, "try.without.catch.or.finally");
1926 }
1927 return F.at(pos).Try(body, catchers.toList(), finalizer);
1928 }
1929 case SWITCH: {
1930 S.nextToken();
1931 JCExpression selector = parExpression();
1932 accept(LBRACE);
1933 List<JCCase> cases = switchBlockStatementGroups();
1934 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1935 accept(RBRACE);
1936 return t;
1937 }
1938 case SYNCHRONIZED: {
1939 S.nextToken();
1940 JCExpression lock = parExpression();
1941 JCBlock body = block();
1942 return F.at(pos).Synchronized(lock, body);
1943 }
1944 case RETURN: {
1945 S.nextToken();
1946 JCExpression result = S.token() == SEMI ? null : parseExpression();
1947 JCReturn t = to(F.at(pos).Return(result));
2368 S.nextToken();
2369 init = variableInitializer();
2370 }
2371 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2372 JCVariableDecl result =
2373 toP(F.at(pos).VarDef(mods, name, type, init));
2374 attach(result, dc);
2375 return result;
2376 }
2377
2378 /** VariableDeclaratorId = Ident BracketsOpt
2379 */
2380 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2381 int pos = S.pos();
2382 Name name = ident();
2383 if ((mods.flags & Flags.VARARGS) == 0)
2384 type = bracketsOpt(type);
2385 return toP(F.at(pos).VarDef(mods, name, type, null));
2386 }
2387
2388 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2389 */
2390 public JCTree.JCCompilationUnit parseCompilationUnit() {
2391 int pos = S.pos();
2392 JCExpression pid = null;
2393 String dc = S.docComment();
2394 JCModifiers mods = null;
2395 List<JCAnnotation> packageAnnotations = List.nil();
2396 if (S.token() == MONKEYS_AT)
2397 mods = modifiersOpt();
2398
2399 if (S.token() == PACKAGE) {
2400 if (mods != null) {
2401 checkNoMods(mods.flags);
2402 packageAnnotations = mods.annotations;
2403 mods = null;
2404 }
2405 S.nextToken();
2406 pid = qualident();
2407 accept(SEMI);
3201 }
3202 }
3203 void checkTypeAnnotations() {
3204 if (!allowTypeAnnotations) {
3205 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3206 allowTypeAnnotations = true;
3207 }
3208 }
3209 void checkDiamond() {
3210 if (!allowDiamond) {
3211 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3212 allowDiamond = true;
3213 }
3214 }
3215 void checkMulticatch() {
3216 if (!allowMulticatch) {
3217 log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3218 allowMulticatch = true;
3219 }
3220 }
3221 }
|
114 /** Construct a parser from a given scanner, tree factory and log.
115 */
116 protected JavacParser(ParserFactory fac,
117 Lexer S,
118 boolean keepDocComments,
119 boolean keepLineMap) {
120 this.S = S;
121 S.nextToken(); // prime the pump
122 this.F = fac.F;
123 this.log = fac.log;
124 this.names = fac.names;
125 this.keywords = fac.keywords;
126 this.source = fac.source;
127 this.allowGenerics = source.allowGenerics();
128 this.allowVarargs = source.allowVarargs();
129 this.allowAsserts = source.allowAsserts();
130 this.allowEnums = source.allowEnums();
131 this.allowForeach = source.allowForeach();
132 this.allowStaticImport = source.allowStaticImport();
133 this.allowAnnotations = source.allowAnnotations();
134 this.allowARM = source.allowAutomaticResourceManagement();
135 this.allowDiamond = source.allowDiamond();
136 this.allowMulticatch = source.allowMulticatch();
137 this.allowTypeAnnotations = source.allowTypeAnnotations();
138 this.keepDocComments = keepDocComments;
139 if (keepDocComments)
140 docComments = new HashMap<JCTree,String>();
141 this.keepLineMap = keepLineMap;
142 this.errorTree = F.Erroneous();
143 this.debugJSR308 = fac.options.get("TA:parser") != null;
144 }
145
146 /** Switch: debug output for type-annotations operations
147 */
148 boolean debugJSR308;
149
150 /** Switch: Should generics be recognized?
151 */
152 boolean allowGenerics;
153
154 /** Switch: Should diamond operator be recognized?
170 /** Switch: should we recognize enums, or just give a warning?
171 */
172 boolean allowEnums;
173
174 /** Switch: should we recognize foreach?
175 */
176 boolean allowForeach;
177
178 /** Switch: should we recognize foreach?
179 */
180 boolean allowStaticImport;
181
182 /** Switch: should we recognize annotations?
183 */
184 boolean allowAnnotations;
185
186 /** Switch: should we recognize type annotations?
187 */
188 boolean allowTypeAnnotations;
189
190 /** Switch: should we recognize automatic resource management?
191 */
192 boolean allowARM;
193
194 /** Switch: should we keep docComments?
195 */
196 boolean keepDocComments;
197
198 /** Switch: should we keep line table?
199 */
200 boolean keepLineMap;
201
202 /** When terms are parsed, the mode determines which is expected:
203 * mode = EXPR : an expression
204 * mode = TYPE : a type
205 * mode = NOPARAMS : no parameters allowed for type
206 * mode = TYPEARG : type argument
207 */
208 static final int EXPR = 0x1;
209 static final int TYPE = 0x2;
210 static final int NOPARAMS = 0x4;
211 static final int TYPEARG = 0x8;
212 static final int DIAMOND = 0x10;
213
1830 if (S.pos() == lastErrPos)
1831 return stats.toList();
1832 if (S.pos() <= errorEndPos) {
1833 skip(false, true, true, true);
1834 lastErrPos = S.pos();
1835 }
1836
1837 // ensure no dangling /** @deprecated */ active
1838 S.resetDeprecatedFlag();
1839 }
1840 }
1841
1842 /** Statement =
1843 * Block
1844 * | IF ParExpression Statement [ELSE Statement]
1845 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1846 * | FOR "(" FormalParameter : Expression ")" Statement
1847 * | WHILE ParExpression Statement
1848 * | DO Statement WHILE ParExpression ";"
1849 * | TRY Block ( Catches | [Catches] FinallyPart )
1850 * | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
1851 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1852 * | SYNCHRONIZED ParExpression Block
1853 * | RETURN [Expression] ";"
1854 * | THROW Expression ";"
1855 * | BREAK [Ident] ";"
1856 * | CONTINUE [Ident] ";"
1857 * | ASSERT Expression [ ":" Expression ] ";"
1858 * | ";"
1859 * | ExpressionStatement
1860 * | Ident ":" Statement
1861 */
1862 @SuppressWarnings("fallthrough")
1863 public JCStatement parseStatement() {
1864 int pos = S.pos();
1865 switch (S.token()) {
1866 case LBRACE:
1867 return block();
1868 case IF: {
1869 S.nextToken();
1870 JCExpression cond = parExpression();
1901 return F.at(pos).ForLoop(inits, cond, steps, body);
1902 }
1903 }
1904 case WHILE: {
1905 S.nextToken();
1906 JCExpression cond = parExpression();
1907 JCStatement body = parseStatement();
1908 return F.at(pos).WhileLoop(cond, body);
1909 }
1910 case DO: {
1911 S.nextToken();
1912 JCStatement body = parseStatement();
1913 accept(WHILE);
1914 JCExpression cond = parExpression();
1915 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1916 accept(SEMI);
1917 return t;
1918 }
1919 case TRY: {
1920 S.nextToken();
1921 List<JCTree> resources = List.<JCTree>nil();
1922 if (S.token() == LPAREN) {
1923 checkAutomaticResourceManagement();
1924 S.nextToken();
1925 resources = resourceDeclarators();
1926 accept(RPAREN);
1927 }
1928 JCBlock body = block();
1929 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1930 JCBlock finalizer = null;
1931 if (S.token() == CATCH || S.token() == FINALLY) {
1932 while (S.token() == CATCH) catchers.append(catchClause());
1933 if (S.token() == FINALLY) {
1934 S.nextToken();
1935 finalizer = block();
1936 }
1937 } else {
1938 if (allowARM) {
1939 if (resources.isEmpty())
1940 log.error(pos, "try.without.catch.finally.or.resource.decls");
1941 } else
1942 log.error(pos, "try.without.catch.or.finally");
1943 }
1944 return F.at(pos).Try(body, catchers.toList(), finalizer, resources);
1945 }
1946 case SWITCH: {
1947 S.nextToken();
1948 JCExpression selector = parExpression();
1949 accept(LBRACE);
1950 List<JCCase> cases = switchBlockStatementGroups();
1951 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1952 accept(RBRACE);
1953 return t;
1954 }
1955 case SYNCHRONIZED: {
1956 S.nextToken();
1957 JCExpression lock = parExpression();
1958 JCBlock body = block();
1959 return F.at(pos).Synchronized(lock, body);
1960 }
1961 case RETURN: {
1962 S.nextToken();
1963 JCExpression result = S.token() == SEMI ? null : parseExpression();
1964 JCReturn t = to(F.at(pos).Return(result));
2385 S.nextToken();
2386 init = variableInitializer();
2387 }
2388 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2389 JCVariableDecl result =
2390 toP(F.at(pos).VarDef(mods, name, type, init));
2391 attach(result, dc);
2392 return result;
2393 }
2394
2395 /** VariableDeclaratorId = Ident BracketsOpt
2396 */
2397 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2398 int pos = S.pos();
2399 Name name = ident();
2400 if ((mods.flags & Flags.VARARGS) == 0)
2401 type = bracketsOpt(type);
2402 return toP(F.at(pos).VarDef(mods, name, type, null));
2403 }
2404
2405 /** ResourceDeclarators = ResourceDeclarator { ";" ResourceDeclarator }
2406 */
2407 List<JCTree> resourceDeclarators() {
2408 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2409 defs.append(resourceDeclarator());
2410 while (S.token() == SEMI) {
2411 // All but last of multiple declarators subsume a semicolon
2412 storeEnd(defs.elems.last(), S.endPos());
2413 S.nextToken();
2414 defs.append(resourceDeclarator());
2415 }
2416 return defs.toList();
2417 }
2418
2419 /** ResourceDeclarator = LocalVariableDeclaration */
2420 JCTree resourceDeclarator() {
2421 int pos = S.pos();
2422 if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2423 return variableDeclaratorRest(pos, optFinal(0), parseType(),
2424 ident(), true, null);
2425 } else {
2426 JCExpression t = term(EXPR | TYPE);
2427 if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
2428 return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t,
2429 ident(), true, null);
2430 else
2431 return t;
2432 }
2433 }
2434
2435 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2436 */
2437 public JCTree.JCCompilationUnit parseCompilationUnit() {
2438 int pos = S.pos();
2439 JCExpression pid = null;
2440 String dc = S.docComment();
2441 JCModifiers mods = null;
2442 List<JCAnnotation> packageAnnotations = List.nil();
2443 if (S.token() == MONKEYS_AT)
2444 mods = modifiersOpt();
2445
2446 if (S.token() == PACKAGE) {
2447 if (mods != null) {
2448 checkNoMods(mods.flags);
2449 packageAnnotations = mods.annotations;
2450 mods = null;
2451 }
2452 S.nextToken();
2453 pid = qualident();
2454 accept(SEMI);
3248 }
3249 }
3250 void checkTypeAnnotations() {
3251 if (!allowTypeAnnotations) {
3252 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3253 allowTypeAnnotations = true;
3254 }
3255 }
3256 void checkDiamond() {
3257 if (!allowDiamond) {
3258 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3259 allowDiamond = true;
3260 }
3261 }
3262 void checkMulticatch() {
3263 if (!allowMulticatch) {
3264 log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3265 allowMulticatch = true;
3266 }
3267 }
3268 void checkAutomaticResourceManagement() {
3269 if (!allowARM) {
3270 log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
3271 allowARM = true;
3272 }
3273 }
3274 }
|