src/jdk/nashorn/internal/parser/Parser.java

Print this page




 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     /**