175 *
176 * @param scriptName name for the script, given to the parsed FunctionNode
177 *
178 * @return function node resulting from successful parse
179 */
180 public FunctionNode parse(final String scriptName) {
181 final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
182 LOG.info(this, " begin for '", scriptName, "'");
183
184 try {
185 stream = new TokenStream();
186 lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
187
188 // Set up first token (skips opening EOL.)
189 k = -1;
190 next();
191
192 // Begin parse.
193 return program(scriptName);
194 } catch (final Exception e) {
195 // Extract message from exception. The message will be in error
196 // message format.
197 String message = e.getMessage();
198
199 // If empty message.
200 if (message == null) {
201 message = e.toString();
202 }
203
204 // Issue message.
205 if (e instanceof ParserException) {
206 errors.error((ParserException)e);
207 } else {
208 errors.error(message);
209 }
210
211 if (env._dump_on_error) {
212 e.printStackTrace(env.getErr());
213 }
214
215 return null;
216 } finally {
217 final String end = this + " end '" + scriptName + "'";
218 if (Timing.isEnabled()) {
219 Timing.accumulateTime(toString(), System.currentTimeMillis() - t0);
220 LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms");
221 } else {
222 LOG.info(end);
223 }
224 }
225 }
226
227 /**
228 * Skip to a good parsing recovery point.
229 */
230 private void recover(final Exception e) {
231 if (e != null) {
232 // Extract message from exception. The message will be in error
233 // message format.
234 String message = e.getMessage();
235
236 // If empty message.
237 if (message == null) {
238 message = e.toString();
239 }
240
241 // Issue message.
242 if (e instanceof ParserException) {
243 errors.error((ParserException)e);
244 } else {
2407 functionDeclarations.add(varNode);
2408 } else {
2409 appendStatement(varNode);
2410 }
2411 }
2412
2413 return functionNode;
2414 }
2415
2416 /**
2417 * FormalParameterList :
2418 * Identifier
2419 * FormalParameterList , Identifier
2420 *
2421 * See 13
2422 *
2423 * Parse function parameter list.
2424 * @return List of parameter nodes.
2425 */
2426 private List<IdentNode> formalParameterList() {
2427 // Prepare to gather parameters.
2428 final List<IdentNode> parameters = new ArrayList<>();
2429 // Track commas.
2430 boolean first = true;
2431
2432 while (type != RPAREN) {
2433 // Comma prior to every argument except the first.
2434 if (!first) {
2435 expect(COMMARIGHT);
2436 } else {
2437 first = false;
2438 }
2439
2440 // Get and add parameter.
2441 final IdentNode ident = getIdent();
2442
2443 // ECMA 13.1 strict mode restrictions
2444 verifyStrictIdent(ident, "function parameter");
2445
2446 parameters.add(ident);
2447 }
2448
2449 return parameters;
2450 }
2451
2452 /**
|
175 *
176 * @param scriptName name for the script, given to the parsed FunctionNode
177 *
178 * @return function node resulting from successful parse
179 */
180 public FunctionNode parse(final String scriptName) {
181 final long t0 = Timing.isEnabled() ? System.currentTimeMillis() : 0L;
182 LOG.info(this, " begin for '", scriptName, "'");
183
184 try {
185 stream = new TokenStream();
186 lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
187
188 // Set up first token (skips opening EOL.)
189 k = -1;
190 next();
191
192 // Begin parse.
193 return program(scriptName);
194 } catch (final Exception e) {
195 handleParseException(e);
196
197 return null;
198 } finally {
199 final String end = this + " end '" + scriptName + "'";
200 if (Timing.isEnabled()) {
201 Timing.accumulateTime(toString(), System.currentTimeMillis() - t0);
202 LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms");
203 } else {
204 LOG.info(end);
205 }
206 }
207 }
208
209 /**
210 * Parse and return the list of function parameter list. A comma
211 * separated list of function parameter identifiers is expected to be parsed.
212 * Errors will be thrown and the error manager will contain information
213 * if parsing should fail. This method is used to check if parameter Strings
214 * passed to "Function" constructor is a valid or not.
215 *
216 * @return the list of IdentNodes representing the formal parameter list
217 */
218 public List<IdentNode> parseFormalParameterList() {
219 try {
220 stream = new TokenStream();
221 lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
222
223 // Set up first token (skips opening EOL.)
224 k = -1;
225 next();
226
227 return formalParameterList(TokenType.EOF);
228 } catch (final Exception e) {
229 handleParseException(e);
230 return null;
231 }
232 }
233
234 /**
235 * Execute parse and return the resulting function node.
236 * Errors will be thrown and the error manager will contain information
237 * if parsing should fail. This method is used to check if code String
238 * passed to "Function" constructor is a valid function body or not.
239 *
240 * @return function node resulting from successful parse
241 */
242 public FunctionNode parseFunctionBody() {
243 try {
244 stream = new TokenStream();
245 lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
246
247 // Set up first token (skips opening EOL.)
248 k = -1;
249 next();
250
251 // Make a fake token for the function.
252 final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
253 // Set up the function to append elements.
254
255 FunctionNode function = newFunctionNode(
256 functionToken,
257 new IdentNode(functionToken, Token.descPosition(functionToken), RUN_SCRIPT.symbolName()),
258 new ArrayList<IdentNode>(),
259 FunctionNode.Kind.NORMAL);
260
261 functionDeclarations = new ArrayList<>();
262 sourceElements();
263 addFunctionDeclarations(function);
264 functionDeclarations = null;
265
266 expect(EOF);
267
268 function.setFinish(source.getLength() - 1);
269
270 function = restoreFunctionNode(function, token); //commit code
271 function = function.setBody(lc, function.getBody().setNeedsScope(lc));
272 return function;
273 } catch (final Exception e) {
274 handleParseException(e);
275 return null;
276 }
277 }
278
279 private void handleParseException(final Exception e) {
280 // Extract message from exception. The message will be in error
281 // message format.
282 String message = e.getMessage();
283
284 // If empty message.
285 if (message == null) {
286 message = e.toString();
287 }
288
289 // Issue message.
290 if (e instanceof ParserException) {
291 errors.error((ParserException)e);
292 } else {
293 errors.error(message);
294 }
295
296 if (env._dump_on_error) {
297 e.printStackTrace(env.getErr());
298 }
299 }
300
301 /**
302 * Skip to a good parsing recovery point.
303 */
304 private void recover(final Exception e) {
305 if (e != null) {
306 // Extract message from exception. The message will be in error
307 // message format.
308 String message = e.getMessage();
309
310 // If empty message.
311 if (message == null) {
312 message = e.toString();
313 }
314
315 // Issue message.
316 if (e instanceof ParserException) {
317 errors.error((ParserException)e);
318 } else {
2481 functionDeclarations.add(varNode);
2482 } else {
2483 appendStatement(varNode);
2484 }
2485 }
2486
2487 return functionNode;
2488 }
2489
2490 /**
2491 * FormalParameterList :
2492 * Identifier
2493 * FormalParameterList , Identifier
2494 *
2495 * See 13
2496 *
2497 * Parse function parameter list.
2498 * @return List of parameter nodes.
2499 */
2500 private List<IdentNode> formalParameterList() {
2501 return formalParameterList(RPAREN);
2502 }
2503 /**
2504 * Same as the other method of the same name - except that the end
2505 * token type expected is passed as argument to this method.
2506 *
2507 * FormalParameterList :
2508 * Identifier
2509 * FormalParameterList , Identifier
2510 *
2511 * See 13
2512 *
2513 * Parse function parameter list.
2514 * @return List of parameter nodes.
2515 */
2516 private List<IdentNode> formalParameterList(final TokenType endType) {
2517 // Prepare to gather parameters.
2518 final List<IdentNode> parameters = new ArrayList<>();
2519 // Track commas.
2520 boolean first = true;
2521
2522 while (type != endType) {
2523 // Comma prior to every argument except the first.
2524 if (!first) {
2525 expect(COMMARIGHT);
2526 } else {
2527 first = false;
2528 }
2529
2530 // Get and add parameter.
2531 final IdentNode ident = getIdent();
2532
2533 // ECMA 13.1 strict mode restrictions
2534 verifyStrictIdent(ident, "function parameter");
2535
2536 parameters.add(ident);
2537 }
2538
2539 return parameters;
2540 }
2541
2542 /**
|