663 * -----------------------------------------------------------------------
664 *
665 * Grammar based on
666 *
667 * ECMAScript Language Specification
668 * ECMA-262 5th Edition / December 2009
669 *
670 * -----------------------------------------------------------------------
671 */
672
673 /**
674 * Program :
675 * SourceElements?
676 *
677 * See 14
678 *
679 * Parse the top level script.
680 */
681 private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
682 // Make a pseudo-token for the script holding its start and length.
683 final long functionToken = Token.toDesc(FUNCTION, getProgramStartPosition(token), source.getLength());
684 final int functionLine = line;
685 // Set up the script to append elements.
686
687 FunctionNode script = newFunctionNode(
688 functionToken,
689 new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
690 new ArrayList<IdentNode>(),
691 FunctionNode.Kind.SCRIPT,
692 functionLine);
693
694 functionDeclarations = new ArrayList<>();
695 sourceElements(allowPropertyFunction);
696 addFunctionDeclarations(script);
697 functionDeclarations = null;
698
699 expect(EOF);
700
701 script.setFinish(source.getLength() - 1);
702
703 script = restoreFunctionNode(script, token); //commit code
704 script = script.setBody(lc, script.getBody().setNeedsScope(lc));
705 // user may have directive comment to set sourceURL
706 if (sourceURL != null) {
707 script = script.setSourceURL(lc, sourceURL);
708 }
709
710 return script;
711 }
712
713 /**
714 * Returns the start position of the program based on its first token. Normally returns the position of the token
715 * itself, except in case of string tokens which report their position past their opening delimiter and thus need
716 * to have one subtracted from their position.
717 * @param firstToken the first token of the program
718 * @return the start position of the program
719 */
720 private static int getProgramStartPosition(final long firstToken) {
721 final int start = Token.descPosition(firstToken);
722 switch(Token.descType(firstToken)) {
723 case STRING: case ESCSTRING: case EXECSTRING: return start - 1;
724 default: return start;
725 }
726 }
727 /**
728 * Directive value or null if statement is not a directive.
729 *
730 * @param stmt Statement to be checked
731 * @return Directive value if the given statement is a directive
732 */
733 private String getDirective(final Node stmt) {
734 if (stmt instanceof ExpressionStatement) {
735 final Node expr = ((ExpressionStatement)stmt).getExpression();
736 if (expr instanceof LiteralNode) {
737 final LiteralNode<?> lit = (LiteralNode<?>)expr;
738 final long litToken = lit.getToken();
739 final TokenType tt = Token.descType(litToken);
740 // A directive is either a string or an escape string
741 if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
742 // Make sure that we don't unescape anything. Return as seen in source!
743 return source.getString(lit.getStart(), Token.descLength(litToken));
744 }
745 }
746 }
|
663 * -----------------------------------------------------------------------
664 *
665 * Grammar based on
666 *
667 * ECMAScript Language Specification
668 * ECMA-262 5th Edition / December 2009
669 *
670 * -----------------------------------------------------------------------
671 */
672
673 /**
674 * Program :
675 * SourceElements?
676 *
677 * See 14
678 *
679 * Parse the top level script.
680 */
681 private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
682 // Make a pseudo-token for the script holding its start and length.
683 final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
684 final int functionLine = line;
685 // Set up the script to append elements.
686
687 FunctionNode script = newFunctionNode(
688 functionToken,
689 new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
690 new ArrayList<IdentNode>(),
691 FunctionNode.Kind.SCRIPT,
692 functionLine);
693
694 functionDeclarations = new ArrayList<>();
695 sourceElements(allowPropertyFunction);
696 addFunctionDeclarations(script);
697 functionDeclarations = null;
698
699 expect(EOF);
700
701 script.setFinish(source.getLength() - 1);
702
703 script = restoreFunctionNode(script, token); //commit code
704 script = script.setBody(lc, script.getBody().setNeedsScope(lc));
705 // user may have directive comment to set sourceURL
706 if (sourceURL != null) {
707 script = script.setSourceURL(lc, sourceURL);
708 }
709
710 return script;
711 }
712
713 /**
714 * Directive value or null if statement is not a directive.
715 *
716 * @param stmt Statement to be checked
717 * @return Directive value if the given statement is a directive
718 */
719 private String getDirective(final Node stmt) {
720 if (stmt instanceof ExpressionStatement) {
721 final Node expr = ((ExpressionStatement)stmt).getExpression();
722 if (expr instanceof LiteralNode) {
723 final LiteralNode<?> lit = (LiteralNode<?>)expr;
724 final long litToken = lit.getToken();
725 final TokenType tt = Token.descType(litToken);
726 // A directive is either a string or an escape string
727 if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
728 // Make sure that we don't unescape anything. Return as seen in source!
729 return source.getString(lit.getStart(), Token.descLength(litToken));
730 }
731 }
732 }
|