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
1829 if (S.pos() == lastErrPos)
1830 return stats.toList();
1831 if (S.pos() <= errorEndPos) {
1832 skip(false, true, true, true);
1833 lastErrPos = S.pos();
1834 }
1835
1836 // ensure no dangling /** @deprecated */ active
1837 S.resetDeprecatedFlag();
1838 }
1839 }
1840
1841 /** Statement =
1842 * Block
1843 * | IF ParExpression Statement [ELSE Statement]
1844 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1845 * | FOR "(" FormalParameter : Expression ")" Statement
1846 * | WHILE ParExpression Statement
1847 * | DO Statement WHILE ParExpression ";"
1848 * | TRY Block ( Catches | [Catches] FinallyPart )
1849 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1850 * | SYNCHRONIZED ParExpression Block
1851 * | RETURN [Expression] ";"
1852 * | THROW Expression ";"
1853 * | BREAK [Ident] ";"
1854 * | CONTINUE [Ident] ";"
1855 * | ASSERT Expression [ ":" Expression ] ";"
1856 * | ";"
1857 * | ExpressionStatement
1858 * | Ident ":" Statement
1859 */
1860 @SuppressWarnings("fallthrough")
1861 public JCStatement parseStatement() {
1862 int pos = S.pos();
1863 switch (S.token()) {
1864 case LBRACE:
1865 return block();
1866 case IF: {
1867 S.nextToken();
1868 JCExpression cond = parExpression();
1899 return F.at(pos).ForLoop(inits, cond, steps, body);
1900 }
1901 }
1902 case WHILE: {
1903 S.nextToken();
1904 JCExpression cond = parExpression();
1905 JCStatement body = parseStatement();
1906 return F.at(pos).WhileLoop(cond, body);
1907 }
1908 case DO: {
1909 S.nextToken();
1910 JCStatement body = parseStatement();
1911 accept(WHILE);
1912 JCExpression cond = parExpression();
1913 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1914 accept(SEMI);
1915 return t;
1916 }
1917 case TRY: {
1918 S.nextToken();
1919 JCBlock body = block();
1920 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1921 JCBlock finalizer = null;
1922 if (S.token() == CATCH || S.token() == FINALLY) {
1923 while (S.token() == CATCH) catchers.append(catchClause());
1924 if (S.token() == FINALLY) {
1925 S.nextToken();
1926 finalizer = block();
1927 }
1928 } else {
1929 log.error(pos, "try.without.catch.or.finally");
1930 }
1931 return F.at(pos).Try(body, catchers.toList(), finalizer);
1932 }
1933 case SWITCH: {
1934 S.nextToken();
1935 JCExpression selector = parExpression();
1936 accept(LBRACE);
1937 List<JCCase> cases = switchBlockStatementGroups();
1938 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1939 accept(RBRACE);
1940 return t;
1941 }
1942 case SYNCHRONIZED: {
1943 S.nextToken();
1944 JCExpression lock = parExpression();
1945 JCBlock body = block();
1946 return F.at(pos).Synchronized(lock, body);
1947 }
1948 case RETURN: {
1949 S.nextToken();
1950 JCExpression result = S.token() == SEMI ? null : parseExpression();
1951 JCReturn t = to(F.at(pos).Return(result));
2372 S.nextToken();
2373 init = variableInitializer();
2374 }
2375 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2376 JCVariableDecl result =
2377 toP(F.at(pos).VarDef(mods, name, type, init));
2378 attach(result, dc);
2379 return result;
2380 }
2381
2382 /** VariableDeclaratorId = Ident BracketsOpt
2383 */
2384 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2385 int pos = S.pos();
2386 Name name = ident();
2387 if ((mods.flags & Flags.VARARGS) == 0)
2388 type = bracketsOpt(type);
2389 return toP(F.at(pos).VarDef(mods, name, type, null));
2390 }
2391
2392 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2393 */
2394 public JCTree.JCCompilationUnit parseCompilationUnit() {
2395 int pos = S.pos();
2396 JCExpression pid = null;
2397 String dc = S.docComment();
2398 JCModifiers mods = null;
2399 List<JCAnnotation> packageAnnotations = List.nil();
2400 if (S.token() == MONKEYS_AT)
2401 mods = modifiersOpt();
2402
2403 if (S.token() == PACKAGE) {
2404 if (mods != null) {
2405 checkNoMods(mods.flags);
2406 packageAnnotations = mods.annotations;
2407 mods = null;
2408 }
2409 S.nextToken();
2410 pid = qualident();
2411 accept(SEMI);
3205 }
3206 }
3207 void checkTypeAnnotations() {
3208 if (!allowTypeAnnotations) {
3209 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3210 allowTypeAnnotations = true;
3211 }
3212 }
3213 void checkDiamond() {
3214 if (!allowDiamond) {
3215 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3216 allowDiamond = true;
3217 }
3218 }
3219 void checkMulticatch() {
3220 if (!allowMulticatch) {
3221 log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3222 allowMulticatch = true;
3223 }
3224 }
3225 }
|
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.allowTWR = source.allowTryWithResources();
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 allowTWR;
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
1834 if (S.pos() == lastErrPos)
1835 return stats.toList();
1836 if (S.pos() <= errorEndPos) {
1837 skip(false, true, true, true);
1838 lastErrPos = S.pos();
1839 }
1840
1841 // ensure no dangling /** @deprecated */ active
1842 S.resetDeprecatedFlag();
1843 }
1844 }
1845
1846 /** Statement =
1847 * Block
1848 * | IF ParExpression Statement [ELSE Statement]
1849 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1850 * | FOR "(" FormalParameter : Expression ")" Statement
1851 * | WHILE ParExpression Statement
1852 * | DO Statement WHILE ParExpression ";"
1853 * | TRY Block ( Catches | [Catches] FinallyPart )
1854 * | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
1855 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1856 * | SYNCHRONIZED ParExpression Block
1857 * | RETURN [Expression] ";"
1858 * | THROW Expression ";"
1859 * | BREAK [Ident] ";"
1860 * | CONTINUE [Ident] ";"
1861 * | ASSERT Expression [ ":" Expression ] ";"
1862 * | ";"
1863 * | ExpressionStatement
1864 * | Ident ":" Statement
1865 */
1866 @SuppressWarnings("fallthrough")
1867 public JCStatement parseStatement() {
1868 int pos = S.pos();
1869 switch (S.token()) {
1870 case LBRACE:
1871 return block();
1872 case IF: {
1873 S.nextToken();
1874 JCExpression cond = parExpression();
1905 return F.at(pos).ForLoop(inits, cond, steps, body);
1906 }
1907 }
1908 case WHILE: {
1909 S.nextToken();
1910 JCExpression cond = parExpression();
1911 JCStatement body = parseStatement();
1912 return F.at(pos).WhileLoop(cond, body);
1913 }
1914 case DO: {
1915 S.nextToken();
1916 JCStatement body = parseStatement();
1917 accept(WHILE);
1918 JCExpression cond = parExpression();
1919 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1920 accept(SEMI);
1921 return t;
1922 }
1923 case TRY: {
1924 S.nextToken();
1925 List<JCTree> resources = List.<JCTree>nil();
1926 if (S.token() == LPAREN) {
1927 checkAutomaticResourceManagement();
1928 S.nextToken();
1929 resources = resources();
1930 accept(RPAREN);
1931 }
1932 JCBlock body = block();
1933 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1934 JCBlock finalizer = null;
1935 if (S.token() == CATCH || S.token() == FINALLY) {
1936 while (S.token() == CATCH) catchers.append(catchClause());
1937 if (S.token() == FINALLY) {
1938 S.nextToken();
1939 finalizer = block();
1940 }
1941 } else {
1942 if (allowTWR) {
1943 if (resources.isEmpty())
1944 log.error(pos, "try.without.catch.finally.or.resource.decls");
1945 } else
1946 log.error(pos, "try.without.catch.or.finally");
1947 }
1948 return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
1949 }
1950 case SWITCH: {
1951 S.nextToken();
1952 JCExpression selector = parExpression();
1953 accept(LBRACE);
1954 List<JCCase> cases = switchBlockStatementGroups();
1955 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1956 accept(RBRACE);
1957 return t;
1958 }
1959 case SYNCHRONIZED: {
1960 S.nextToken();
1961 JCExpression lock = parExpression();
1962 JCBlock body = block();
1963 return F.at(pos).Synchronized(lock, body);
1964 }
1965 case RETURN: {
1966 S.nextToken();
1967 JCExpression result = S.token() == SEMI ? null : parseExpression();
1968 JCReturn t = to(F.at(pos).Return(result));
2389 S.nextToken();
2390 init = variableInitializer();
2391 }
2392 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2393 JCVariableDecl result =
2394 toP(F.at(pos).VarDef(mods, name, type, init));
2395 attach(result, dc);
2396 return result;
2397 }
2398
2399 /** VariableDeclaratorId = Ident BracketsOpt
2400 */
2401 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2402 int pos = S.pos();
2403 Name name = ident();
2404 if ((mods.flags & Flags.VARARGS) == 0)
2405 type = bracketsOpt(type);
2406 return toP(F.at(pos).VarDef(mods, name, type, null));
2407 }
2408
2409 /** Resources = Resource { ";" Resources }
2410 */
2411 List<JCTree> resources() {
2412 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2413 defs.append(resource());
2414 while (S.token() == SEMI) {
2415 // All but last of multiple declarators subsume a semicolon
2416 storeEnd(defs.elems.last(), S.endPos());
2417 S.nextToken();
2418 defs.append(resource());
2419 }
2420 return defs.toList();
2421 }
2422
2423 /** Resource =
2424 * VariableModifiers Type VariableDeclaratorId = Expression
2425 * | Expression
2426 */
2427 JCTree resource() {
2428 int pos = S.pos();
2429 if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2430 return variableDeclaratorRest(pos, optFinal(0), parseType(),
2431 ident(), true, null);
2432 } else {
2433 JCExpression t = term(EXPR | TYPE);
2434 if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
2435 return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t,
2436 ident(), true, null);
2437 else
2438 return t;
2439 }
2440 }
2441
2442 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2443 */
2444 public JCTree.JCCompilationUnit parseCompilationUnit() {
2445 int pos = S.pos();
2446 JCExpression pid = null;
2447 String dc = S.docComment();
2448 JCModifiers mods = null;
2449 List<JCAnnotation> packageAnnotations = List.nil();
2450 if (S.token() == MONKEYS_AT)
2451 mods = modifiersOpt();
2452
2453 if (S.token() == PACKAGE) {
2454 if (mods != null) {
2455 checkNoMods(mods.flags);
2456 packageAnnotations = mods.annotations;
2457 mods = null;
2458 }
2459 S.nextToken();
2460 pid = qualident();
2461 accept(SEMI);
3255 }
3256 }
3257 void checkTypeAnnotations() {
3258 if (!allowTypeAnnotations) {
3259 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3260 allowTypeAnnotations = true;
3261 }
3262 }
3263 void checkDiamond() {
3264 if (!allowDiamond) {
3265 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3266 allowDiamond = true;
3267 }
3268 }
3269 void checkMulticatch() {
3270 if (!allowMulticatch) {
3271 log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3272 allowMulticatch = true;
3273 }
3274 }
3275 void checkAutomaticResourceManagement() {
3276 if (!allowTWR) {
3277 log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
3278 allowTWR = true;
3279 }
3280 }
3281 }
|