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
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
1900 return F.at(pos).ForLoop(inits, cond, steps, body);
1901 }
1902 }
1903 case WHILE: {
1904 S.nextToken();
1905 JCExpression cond = parExpression();
1906 JCStatement body = parseStatement();
1907 return F.at(pos).WhileLoop(cond, body);
1908 }
1909 case DO: {
1910 S.nextToken();
1911 JCStatement body = parseStatement();
1912 accept(WHILE);
1913 JCExpression cond = parExpression();
1914 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1915 accept(SEMI);
1916 return t;
1917 }
1918 case TRY: {
1919 S.nextToken();
1920 List<JCTree> resources = List.<JCTree>nil();
1921 if (S.token() == LPAREN) {
1922 checkAutomaticResourceManagement();
1923 S.nextToken();
1924 resources = resourceDeclarators();
1925 accept(RPAREN);
1926 }
1927 JCBlock body = block();
1928 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1929 JCBlock finalizer = null;
1930 if (S.token() == CATCH || S.token() == FINALLY) {
1931 while (S.token() == CATCH) catchers.append(catchClause());
1932 if (S.token() == FINALLY) {
1933 S.nextToken();
1934 finalizer = block();
1935 }
1936 } else {
1937 if (allowARM) {
1938 if (resources.isEmpty())
1939 log.error(pos, "try.without.catch.finally.or.resource.decls");
1940 } else
1941 log.error(pos, "try.without.catch.or.finally");
1942 }
1943 return F.at(pos).Try(body, catchers.toList(), finalizer, resources);
1944 }
1945 case SWITCH: {
1946 S.nextToken();
1947 JCExpression selector = parExpression();
1948 accept(LBRACE);
1949 List<JCCase> cases = switchBlockStatementGroups();
1950 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1951 accept(RBRACE);
1952 return t;
1953 }
1954 case SYNCHRONIZED: {
1955 S.nextToken();
1956 JCExpression lock = parExpression();
1957 JCBlock body = block();
1958 return F.at(pos).Synchronized(lock, body);
1959 }
1960 case RETURN: {
1961 S.nextToken();
1962 JCExpression result = S.token() == SEMI ? null : parseExpression();
1963 JCReturn t = to(F.at(pos).Return(result));
2384 S.nextToken();
2385 init = variableInitializer();
2386 }
2387 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2388 JCVariableDecl result =
2389 toP(F.at(pos).VarDef(mods, name, type, init));
2390 attach(result, dc);
2391 return result;
2392 }
2393
2394 /** VariableDeclaratorId = Ident BracketsOpt
2395 */
2396 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2397 int pos = S.pos();
2398 Name name = ident();
2399 if ((mods.flags & Flags.VARARGS) == 0)
2400 type = bracketsOpt(type);
2401 return toP(F.at(pos).VarDef(mods, name, type, null));
2402 }
2403
2404 /** ResourceDeclarators = ResourceDeclarator { "," ResourceDeclarator }
2405 */
2406 List<JCTree> resourceDeclarators() {
2407 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2408 defs.append(resourceDeclarator());
2409 while (S.token() == SEMI) {
2410 // All but last of multiple declarators subsume a semicolon
2411 storeEnd(defs.elems.last(), S.endPos());
2412 S.nextToken();
2413 defs.append(resourceDeclarator());
2414 }
2415 return defs.toList();
2416 }
2417
2418 /** ResourceDeclarator = LocalVariableDeclaration */
2419 JCTree resourceDeclarator() {
2420 if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2421 return variableDeclaratorRest(S.pos(), optFinal(0), parseType(),
2422 ident(), true, null);
2423 } else {
2424 JCExpression t = term(EXPR | TYPE);
2425 if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
2426 return variableDeclaratorRest(S.pos(), modifiersOpt(), t,
2427 ident(), true, null);
2428 else
2429 return t;
2430 }
2431 }
2432
2433 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2434 */
2435 public JCTree.JCCompilationUnit parseCompilationUnit() {
2436 int pos = S.pos();
2437 JCExpression pid = null;
2438 String dc = S.docComment();
2439 JCModifiers mods = null;
2440 List<JCAnnotation> packageAnnotations = List.nil();
2441 if (S.token() == MONKEYS_AT)
2442 mods = modifiersOpt();
2443
2444 if (S.token() == PACKAGE) {
2445 if (mods != null) {
2446 checkNoMods(mods.flags);
2447 packageAnnotations = mods.annotations;
2448 mods = null;
2449 }
2450 S.nextToken();
2451 pid = qualident();
2452 accept(SEMI);
3246 }
3247 }
3248 void checkTypeAnnotations() {
3249 if (!allowTypeAnnotations) {
3250 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3251 allowTypeAnnotations = true;
3252 }
3253 }
3254 void checkDiamond() {
3255 if (!allowDiamond) {
3256 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3257 allowDiamond = true;
3258 }
3259 }
3260 void checkMulticatch() {
3261 if (!allowMulticatch) {
3262 log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3263 allowMulticatch = true;
3264 }
3265 }
3266 void checkAutomaticResourceManagement() {
3267 if (!allowARM) {
3268 log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
3269 allowARM = true;
3270 }
3271 }
3272 }
|