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

changeset 252
544e17632e96
parent 247
5a3f7867e19c
child 253
fb1d7ea3e1b6
equal deleted inserted replaced
251:f3dcb12c8439 252:544e17632e96
273 * Set up a new block. 273 * Set up a new block.
274 * 274 *
275 * @return New block. 275 * @return New block.
276 */ 276 */
277 private Block newBlock() { 277 private Block newBlock() {
278 final Block block = new Block(source, token, Token.descPosition(token)); 278 return lc.push(new Block(token, Token.descPosition(token)));
279 return lc.push(block);
280 } 279 }
281 280
282 /** 281 /**
283 * Set up a new function block. 282 * Set up a new function block.
284 * 283 *
477 default: 476 default:
478 break; 477 break;
479 } 478 }
480 479
481 // Build up node. 480 // Build up node.
482 return new BinaryNode(source, op, lhs, rhs); 481 return new BinaryNode(op, lhs, rhs);
483 } 482 }
484 483
485 /** 484 /**
486 * Reduce increment/decrement to simpler operations. 485 * Reduce increment/decrement to simpler operations.
487 * @param firstToken First token. 486 * @param firstToken First token.
488 * @param tokenType Operation token (INCPREFIX/DEC.) 487 * @param tokenType Operation token (INCPREFIX/DEC.)
489 * @param expression Left hand side expression. 488 * @param expression Left hand side expression.
490 * @param isPostfix Prefix or postfix. 489 * @param isPostfix Prefix or postfix.
491 * @return Reduced expression. 490 * @return Reduced expression.
492 */ 491 */
493 private Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) { 492 private static Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
494 if (isPostfix) { 493 if (isPostfix) {
495 return new UnaryNode(source, Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression); 494 return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
496 } 495 }
497 496
498 return new UnaryNode(source, firstToken, expression); 497 return new UnaryNode(firstToken, expression);
499 } 498 }
500 499
501 /** 500 /**
502 * ----------------------------------------------------------------------- 501 * -----------------------------------------------------------------------
503 * 502 *
522 final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength()); 521 final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
523 // Set up the script to append elements. 522 // Set up the script to append elements.
524 523
525 FunctionNode script = newFunctionNode( 524 FunctionNode script = newFunctionNode(
526 functionToken, 525 functionToken,
527 new IdentNode(source, functionToken, Token.descPosition(functionToken), scriptName), 526 new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
528 new ArrayList<IdentNode>(), 527 new ArrayList<IdentNode>(),
529 FunctionNode.Kind.SCRIPT); 528 FunctionNode.Kind.SCRIPT);
530 529
531 functionDeclarations = new ArrayList<>(); 530 functionDeclarations = new ArrayList<>();
532 sourceElements(); 531 sourceElements();
772 * Parse a statement block. 771 * Parse a statement block.
773 */ 772 */
774 private void block() { 773 private void block() {
775 final Block newBlock = getBlock(true); 774 final Block newBlock = getBlock(true);
776 // Force block execution. 775 // Force block execution.
777 appendStatement(new ExecuteNode(source, newBlock.getToken(), finish, newBlock)); 776 appendStatement(new ExecuteNode(newBlock.getToken(), finish, newBlock));
778 } 777 }
779 778
780 /** 779 /**
781 * StatementList : 780 * StatementList :
782 * Statement 781 * Statement
865 // Get initializer expression. Suppress IN if not statement. 864 // Get initializer expression. Suppress IN if not statement.
866 init = assignmentExpression(!isStatement); 865 init = assignmentExpression(!isStatement);
867 } 866 }
868 867
869 // Allocate var node. 868 // Allocate var node.
870 final VarNode var = new VarNode(source, varToken, finish, name, init); 869 final VarNode var = new VarNode(varToken, finish, name, init);
871 vars.add(var); 870 vars.add(var);
872 appendStatement(var); 871 appendStatement(var);
873 872
874 if (type != COMMARIGHT) { 873 if (type != COMMARIGHT) {
875 break; 874 break;
897 * 896 *
898 * Parse an empty statement. 897 * Parse an empty statement.
899 */ 898 */
900 private void emptyStatement() { 899 private void emptyStatement() {
901 if (env._empty_statements) { 900 if (env._empty_statements) {
902 appendStatement(new EmptyNode(source, token, Token.descPosition(token) + Token.descLength(token))); 901 appendStatement(new EmptyNode(token, Token.descPosition(token) + Token.descLength(token)));
903 } 902 }
904 903
905 // SEMICOLON checked in caller. 904 // SEMICOLON checked in caller.
906 next(); 905 next();
907 } 906 }
921 // Get expression and add as statement. 920 // Get expression and add as statement.
922 final Node expression = expression(); 921 final Node expression = expression();
923 922
924 ExecuteNode executeNode = null; 923 ExecuteNode executeNode = null;
925 if (expression != null) { 924 if (expression != null) {
926 executeNode = new ExecuteNode(source, expressionToken, finish, expression); 925 executeNode = new ExecuteNode(expressionToken, finish, expression);
927 appendStatement(executeNode); 926 appendStatement(executeNode);
928 } else { 927 } else {
929 expect(null); 928 expect(null);
930 } 929 }
931 930
961 if (type == ELSE) { 960 if (type == ELSE) {
962 next(); 961 next();
963 fail = getStatement(); 962 fail = getStatement();
964 } 963 }
965 964
966 appendStatement(new IfNode(source, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail)); 965 appendStatement(new IfNode(ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
967 } 966 }
968 967
969 /** 968 /**
970 * ... IterationStatement: 969 * ... IterationStatement:
971 * ... 970 * ...
978 * 977 *
979 * Parse a FOR statement. 978 * Parse a FOR statement.
980 */ 979 */
981 private void forStatement() { 980 private void forStatement() {
982 // Create FOR node, capturing FOR token. 981 // Create FOR node, capturing FOR token.
983 ForNode forNode = new ForNode(source, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR); 982 ForNode forNode = new ForNode(token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
984 983
985 984
986 // Set up new block for scope of vars. Captures first token. 985 // Set up new block for scope of vars. Captures first token.
987 Block outer = newBlock(); 986 Block outer = newBlock();
988 lc.push(forNode); 987 lc.push(forNode);
1082 } finally { 1081 } finally {
1083 lc.pop(forNode); 1082 lc.pop(forNode);
1084 outer = restoreBlock(outer); 1083 outer = restoreBlock(outer);
1085 } 1084 }
1086 1085
1087 appendStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); 1086 appendStatement(new ExecuteNode(outer.getToken(), outer.getFinish(), outer));
1088 } 1087 }
1089 1088
1090 /** 1089 /**
1091 * ... IterationStatement : 1090 * ... IterationStatement :
1092 * ... 1091 * ...
1118 final long whileToken = token; 1117 final long whileToken = token;
1119 // WHILE tested in caller. 1118 // WHILE tested in caller.
1120 next(); 1119 next();
1121 1120
1122 // Construct WHILE node. 1121 // Construct WHILE node.
1123 WhileNode whileNode = new WhileNode(source, whileToken, Token.descPosition(whileToken), false); 1122 WhileNode whileNode = new WhileNode(whileToken, Token.descPosition(whileToken), false);
1124 lc.push(whileNode); 1123 lc.push(whileNode);
1125 1124
1126 try { 1125 try {
1127 expect(LPAREN); 1126 expect(LPAREN);
1128 whileNode = whileNode.setTest(lc, expression()); 1127 whileNode = whileNode.setTest(lc, expression());
1148 // Capture DO token. 1147 // Capture DO token.
1149 final long doToken = token; 1148 final long doToken = token;
1150 // DO tested in the caller. 1149 // DO tested in the caller.
1151 next(); 1150 next();
1152 1151
1153 WhileNode doWhileNode = new WhileNode(source, doToken, Token.descPosition(doToken), true); 1152 WhileNode doWhileNode = new WhileNode(doToken, Token.descPosition(doToken), true);
1154 lc.push(doWhileNode); 1153 lc.push(doWhileNode);
1155 1154
1156 try { 1155 try {
1157 // Get DO body. 1156 // Get DO body.
1158 doWhileNode = doWhileNode.setBody(lc, getStatement()); 1157 doWhileNode = doWhileNode.setBody(lc, getStatement());
1214 } 1213 }
1215 1214
1216 endOfLine(); 1215 endOfLine();
1217 1216
1218 // Construct and add CONTINUE node. 1217 // Construct and add CONTINUE node.
1219 appendStatement(new ContinueNode(source, continueToken, finish, label == null ? null : new IdentNode(label))); 1218 appendStatement(new ContinueNode(continueToken, finish, label == null ? null : new IdentNode(label)));
1220 } 1219 }
1221 1220
1222 /** 1221 /**
1223 * BreakStatement : 1222 * BreakStatement :
1224 * break Identifier? ; // [no LineTerminator here] 1223 * break Identifier? ; // [no LineTerminator here]
1261 } 1260 }
1262 1261
1263 endOfLine(); 1262 endOfLine();
1264 1263
1265 // Construct and add BREAK node. 1264 // Construct and add BREAK node.
1266 appendStatement(new BreakNode(source, breakToken, finish, label == null ? null : new IdentNode(label))); 1265 appendStatement(new BreakNode(breakToken, finish, label == null ? null : new IdentNode(label)));
1267 } 1266 }
1268 1267
1269 /** 1268 /**
1270 * ReturnStatement : 1269 * ReturnStatement :
1271 * return Expression? ; // [no LineTerminator here] 1270 * return Expression? ; // [no LineTerminator here]
1300 } 1299 }
1301 1300
1302 endOfLine(); 1301 endOfLine();
1303 1302
1304 // Construct and add RETURN node. 1303 // Construct and add RETURN node.
1305 appendStatement(new ReturnNode(source, returnToken, finish, expression)); 1304 appendStatement(new ReturnNode(returnToken, finish, expression));
1306 } 1305 }
1307 1306
1308 /** 1307 /**
1309 * YieldStatement : 1308 * YieldStatement :
1310 * yield Expression? ; // [no LineTerminator here] 1309 * yield Expression? ; // [no LineTerminator here]
1334 } 1333 }
1335 1334
1336 endOfLine(); 1335 endOfLine();
1337 1336
1338 // Construct and add YIELD node. 1337 // Construct and add YIELD node.
1339 appendStatement(new ReturnNode(source, yieldToken, finish, expression)); 1338 appendStatement(new ReturnNode(yieldToken, finish, expression));
1340 } 1339 }
1341 1340
1342 /** 1341 /**
1343 * WithStatement : 1342 * WithStatement :
1344 * with ( Expression ) Statement 1343 * with ( Expression ) Statement
1357 if (isStrictMode) { 1356 if (isStrictMode) {
1358 throw error(AbstractParser.message("strict.no.with"), withToken); 1357 throw error(AbstractParser.message("strict.no.with"), withToken);
1359 } 1358 }
1360 1359
1361 // Get WITH expression. 1360 // Get WITH expression.
1362 WithNode withNode = new WithNode(source, withToken, finish); 1361 WithNode withNode = new WithNode(withToken, finish);
1363 1362
1364 try { 1363 try {
1365 lc.push(withNode); 1364 lc.push(withNode);
1366 expect(LPAREN); 1365 expect(LPAREN);
1367 withNode = withNode.setExpression(lc, expression()); 1366 withNode = withNode.setExpression(lc, expression());
1400 final long switchToken = token; 1399 final long switchToken = token;
1401 // SWITCH tested in caller. 1400 // SWITCH tested in caller.
1402 next(); 1401 next();
1403 1402
1404 // Create and add switch statement. 1403 // Create and add switch statement.
1405 SwitchNode switchNode = new SwitchNode(source, switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null); 1404 SwitchNode switchNode = new SwitchNode(switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null);
1406 lc.push(switchNode); 1405 lc.push(switchNode);
1407 1406
1408 try { 1407 try {
1409 expect(LPAREN); 1408 expect(LPAREN);
1410 switchNode = switchNode.setExpression(lc, expression()); 1409 switchNode = switchNode.setExpression(lc, expression());
1442 1441
1443 expect(COLON); 1442 expect(COLON);
1444 1443
1445 // Get CASE body. 1444 // Get CASE body.
1446 final Block statements = getBlock(false); 1445 final Block statements = getBlock(false);
1447 final CaseNode caseNode = new CaseNode(source, caseToken, finish, caseExpression, statements); 1446 final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
1448 statements.setFinish(finish); 1447 statements.setFinish(finish);
1449 1448
1450 if (caseExpression == null) { 1449 if (caseExpression == null) {
1451 defaultCase = caseNode; 1450 defaultCase = caseNode;
1452 } 1451 }
1482 1481
1483 if (lc.findLabel(ident.getName()) != null) { 1482 if (lc.findLabel(ident.getName()) != null) {
1484 throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken); 1483 throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
1485 } 1484 }
1486 1485
1487 LabelNode labelNode = new LabelNode(source, labelToken, finish, ident, null); 1486 LabelNode labelNode = new LabelNode(labelToken, finish, ident, null);
1488 try { 1487 try {
1489 lc.push(labelNode); 1488 lc.push(labelNode);
1490 labelNode = labelNode.setBody(lc, getStatement()); 1489 labelNode = labelNode.setBody(lc, getStatement());
1491 labelNode.setFinish(finish); 1490 labelNode.setFinish(finish);
1492 appendStatement(labelNode); 1491 appendStatement(labelNode);
1528 throw error(AbstractParser.message("expected.operand", type.getNameOrType())); 1527 throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
1529 } 1528 }
1530 1529
1531 endOfLine(); 1530 endOfLine();
1532 1531
1533 appendStatement(new ThrowNode(source, throwToken, finish, expression)); 1532 appendStatement(new ThrowNode(throwToken, finish, expression));
1534 } 1533 }
1535 1534
1536 /** 1535 /**
1537 * TryStatement : 1536 * TryStatement :
1538 * try Block Catch 1537 * try Block Catch
1586 1585
1587 Block catchBlock = newBlock(); 1586 Block catchBlock = newBlock();
1588 try { 1587 try {
1589 // Get CATCH body. 1588 // Get CATCH body.
1590 final Block catchBody = getBlock(true); 1589 final Block catchBody = getBlock(true);
1591 final CatchNode catchNode = new CatchNode(source, catchToken, finish, exception, ifExpression, catchBody); 1590 final CatchNode catchNode = new CatchNode(catchToken, finish, exception, ifExpression, catchBody);
1592 appendStatement(catchNode); 1591 appendStatement(catchNode);
1593 } finally { 1592 } finally {
1594 catchBlock = restoreBlock(catchBlock); 1593 catchBlock = restoreBlock(catchBlock);
1595 catchBlocks.add(catchBlock); 1594 catchBlocks.add(catchBlock);
1596 } 1595 }
1612 // Need at least one catch or a finally. 1611 // Need at least one catch or a finally.
1613 if (catchBlocks.isEmpty() && finallyStatements == null) { 1612 if (catchBlocks.isEmpty() && finallyStatements == null) {
1614 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken); 1613 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
1615 } 1614 }
1616 1615
1617 final TryNode tryNode = new TryNode(source, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements); 1616 final TryNode tryNode = new TryNode(tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements);
1618 // Add try. 1617 // Add try.
1619 assert lc.peek() == outer; 1618 assert lc.peek() == outer;
1620 appendStatement(tryNode); 1619 appendStatement(tryNode);
1621 1620
1622 tryNode.setFinish(finish); 1621 tryNode.setFinish(finish);
1624 1623
1625 } finally { 1624 } finally {
1626 outer = restoreBlock(outer); 1625 outer = restoreBlock(outer);
1627 } 1626 }
1628 1627
1629 appendStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); 1628 appendStatement(new ExecuteNode(outer.getToken(), outer.getFinish(), outer));
1630 } 1629 }
1631 1630
1632 /** 1631 /**
1633 * DebuggerStatement : 1632 * DebuggerStatement :
1634 * debugger ; 1633 * debugger ;
1641 // Capture DEBUGGER token. 1640 // Capture DEBUGGER token.
1642 final long debuggerToken = token; 1641 final long debuggerToken = token;
1643 // DEBUGGER tested in caller. 1642 // DEBUGGER tested in caller.
1644 next(); 1643 next();
1645 endOfLine(); 1644 endOfLine();
1646 appendStatement(new RuntimeNode(source, debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>())); 1645 appendStatement(new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>()));
1647 } 1646 }
1648 1647
1649 /** 1648 /**
1650 * PrimaryExpression : 1649 * PrimaryExpression :
1651 * this 1650 * this
1667 1666
1668 switch (type) { 1667 switch (type) {
1669 case THIS: 1668 case THIS:
1670 final String name = type.getName(); 1669 final String name = type.getName();
1671 next(); 1670 next();
1672 return new IdentNode(source, primaryToken, finish, name); 1671 return new IdentNode(primaryToken, finish, name);
1673 case IDENT: 1672 case IDENT:
1674 final IdentNode ident = getIdent(); 1673 final IdentNode ident = getIdent();
1675 if (ident == null) { 1674 if (ident == null) {
1676 break; 1675 break;
1677 } 1676 }
1691 return getLiteral(); 1690 return getLiteral();
1692 case EXECSTRING: 1691 case EXECSTRING:
1693 return execString(primaryToken); 1692 return execString(primaryToken);
1694 case FALSE: 1693 case FALSE:
1695 next(); 1694 next();
1696 return LiteralNode.newInstance(source, primaryToken, finish, false); 1695 return LiteralNode.newInstance(primaryToken, finish, false);
1697 case TRUE: 1696 case TRUE:
1698 next(); 1697 next();
1699 return LiteralNode.newInstance(source, primaryToken, finish, true); 1698 return LiteralNode.newInstance(primaryToken, finish, true);
1700 case NULL: 1699 case NULL:
1701 next(); 1700 next();
1702 return LiteralNode.newInstance(source, primaryToken, finish); 1701 return LiteralNode.newInstance(primaryToken, finish);
1703 case LBRACKET: 1702 case LBRACKET:
1704 return arrayLiteral(); 1703 return arrayLiteral();
1705 case LBRACE: 1704 case LBRACE:
1706 return objectLiteral(); 1705 return objectLiteral();
1707 case LPAREN: 1706 case LPAREN:
1734 * @param primaryToken Original string token. 1733 * @param primaryToken Original string token.
1735 * @return callNode to $EXEC. 1734 * @return callNode to $EXEC.
1736 */ 1735 */
1737 Node execString(final long primaryToken) { 1736 Node execString(final long primaryToken) {
1738 // Synthesize an ident to call $EXEC. 1737 // Synthesize an ident to call $EXEC.
1739 final IdentNode execIdent = new IdentNode(source, primaryToken, finish, ScriptingFunctions.EXEC_NAME); 1738 final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
1740 // Skip over EXECSTRING. 1739 // Skip over EXECSTRING.
1741 next(); 1740 next();
1742 // Set up argument list for call. 1741 // Set up argument list for call.
1743 final List<Node> arguments = new ArrayList<>(); 1742 final List<Node> arguments = new ArrayList<>();
1744 // Skip beginning of edit string expression. 1743 // Skip beginning of edit string expression.
1746 // Add the following expression to arguments. 1745 // Add the following expression to arguments.
1747 arguments.add(expression()); 1746 arguments.add(expression());
1748 // Skip ending of edit string expression. 1747 // Skip ending of edit string expression.
1749 expect(RBRACE); 1748 expect(RBRACE);
1750 1749
1751 return new CallNode(source, primaryToken, finish, execIdent, arguments); 1750 return new CallNode(primaryToken, finish, execIdent, arguments);
1752 } 1751 }
1753 1752
1754 /** 1753 /**
1755 * ArrayLiteral : 1754 * ArrayLiteral :
1756 * [ Elision? ] 1755 * [ Elision? ]
1817 elision = false; 1816 elision = false;
1818 break; 1817 break;
1819 } 1818 }
1820 } 1819 }
1821 1820
1822 return LiteralNode.newInstance(source, arrayToken, finish, elements); 1821 return LiteralNode.newInstance(arrayToken, finish, elements);
1823 } 1822 }
1824 1823
1825 /** 1824 /**
1826 * ObjectLiteral : 1825 * ObjectLiteral :
1827 * { } 1826 * { }
1924 if (value != null) { 1923 if (value != null) {
1925 if (prevValue == null) { 1924 if (prevValue == null) {
1926 map.put(key, newProperty = newProperty.setValue(value)); 1925 map.put(key, newProperty = newProperty.setValue(value));
1927 } else { 1926 } else {
1928 final long propertyToken = Token.recast(newProperty.getToken(), COMMARIGHT); 1927 final long propertyToken = Token.recast(newProperty.getToken(), COMMARIGHT);
1929 map.put(key, newProperty = newProperty.setValue(new BinaryNode(source, propertyToken, prevValue, value))); 1928 map.put(key, newProperty = newProperty.setValue(new BinaryNode(propertyToken, prevValue, value)));
1930 } 1929 }
1931 1930
1932 map.put(key, newProperty = newProperty.setGetter(null).setSetter(null)); 1931 map.put(key, newProperty = newProperty.setGetter(null).setSetter(null));
1933 } 1932 }
1934 1933
1941 } 1940 }
1942 break; 1941 break;
1943 } 1942 }
1944 } 1943 }
1945 1944
1946 return new ObjectNode(source, objectToken, finish, new ArrayList<Node>(map.values())); 1945 return new ObjectNode(objectToken, finish, new ArrayList<Node>(map.values()));
1947 } 1946 }
1948 1947
1949 /** 1948 /**
1950 * PropertyName : 1949 * PropertyName :
1951 * IdentifierName 1950 * IdentifierName
2011 2010
2012 switch (ident) { 2011 switch (ident) {
2013 case "get": 2012 case "get":
2014 final PropertyKey getIdent = propertyName(); 2013 final PropertyKey getIdent = propertyName();
2015 final String getterName = getIdent.getPropertyName(); 2014 final String getterName = getIdent.getPropertyName();
2016 final IdentNode getNameNode = new IdentNode(source, ((Node)getIdent).getToken(), finish, "get " + getterName); 2015 final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + getterName);
2017 expect(LPAREN); 2016 expect(LPAREN);
2018 expect(RPAREN); 2017 expect(RPAREN);
2019 functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER); 2018 functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER);
2020 return new PropertyNode(source, propertyToken, finish, getIdent, null, functionNode, null); 2019 return new PropertyNode(propertyToken, finish, getIdent, null, functionNode, null);
2021 2020
2022 case "set": 2021 case "set":
2023 final PropertyKey setIdent = propertyName(); 2022 final PropertyKey setIdent = propertyName();
2024 final String setterName = setIdent.getPropertyName(); 2023 final String setterName = setIdent.getPropertyName();
2025 final IdentNode setNameNode = new IdentNode(source, ((Node)setIdent).getToken(), finish, "set " + setterName); 2024 final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + setterName);
2026 expect(LPAREN); 2025 expect(LPAREN);
2027 final IdentNode argIdent = getIdent(); 2026 final IdentNode argIdent = getIdent();
2028 verifyStrictIdent(argIdent, "setter argument"); 2027 verifyStrictIdent(argIdent, "setter argument");
2029 expect(RPAREN); 2028 expect(RPAREN);
2030 List<IdentNode> parameters = new ArrayList<>(); 2029 List<IdentNode> parameters = new ArrayList<>();
2031 parameters.add(argIdent); 2030 parameters.add(argIdent);
2032 functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER); 2031 functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
2033 return new PropertyNode(source, propertyToken, finish, setIdent, null, null, functionNode); 2032 return new PropertyNode(propertyToken, finish, setIdent, null, null, functionNode);
2034 2033
2035 default: 2034 default:
2036 break; 2035 break;
2037 } 2036 }
2038 } 2037 }
2039 2038
2040 propertyName = new IdentNode(source, propertyToken, finish, ident); 2039 propertyName = new IdentNode(propertyToken, finish, ident);
2041 } else { 2040 } else {
2042 propertyName = propertyName(); 2041 propertyName = propertyName();
2043 } 2042 }
2044 2043
2045 expect(COLON); 2044 expect(COLON);
2046 2045
2047 return new PropertyNode(source, propertyToken, finish, propertyName, assignmentExpression(false), null, null); 2046 return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
2048 } 2047 }
2049 2048
2050 /** 2049 /**
2051 * LeftHandSideExpression : 2050 * LeftHandSideExpression :
2052 * NewExpression 2051 * NewExpression
2074 // Catch special functions. 2073 // Catch special functions.
2075 if (lhs instanceof IdentNode) { 2074 if (lhs instanceof IdentNode) {
2076 detectSpecialFunction((IdentNode)lhs); 2075 detectSpecialFunction((IdentNode)lhs);
2077 } 2076 }
2078 2077
2079 lhs = new CallNode(source, callToken, finish, lhs, arguments); 2078 lhs = new CallNode(callToken, finish, lhs, arguments);
2080 } 2079 }
2081 2080
2082 loop: 2081 loop:
2083 while (true) { 2082 while (true) {
2084 // Capture token. 2083 // Capture token.
2088 case LPAREN: 2087 case LPAREN:
2089 // Get NEW or FUNCTION arguments. 2088 // Get NEW or FUNCTION arguments.
2090 final List<Node> arguments = argumentList(); 2089 final List<Node> arguments = argumentList();
2091 2090
2092 // Create call node. 2091 // Create call node.
2093 lhs = new CallNode(source, callToken, finish, lhs, arguments); 2092 lhs = new CallNode(callToken, finish, lhs, arguments);
2094 2093
2095 break; 2094 break;
2096 2095
2097 case LBRACKET: 2096 case LBRACKET:
2098 next(); 2097 next();
2101 final Node rhs = expression(); 2100 final Node rhs = expression();
2102 2101
2103 expect(RBRACKET); 2102 expect(RBRACKET);
2104 2103
2105 // Create indexing node. 2104 // Create indexing node.
2106 lhs = new IndexNode(source, callToken, finish, lhs, rhs); 2105 lhs = new IndexNode(callToken, finish, lhs, rhs);
2107 2106
2108 break; 2107 break;
2109 2108
2110 case PERIOD: 2109 case PERIOD:
2111 next(); 2110 next();
2112 2111
2113 final IdentNode property = getIdentifierName(); 2112 final IdentNode property = getIdentifierName();
2114 2113
2115 // Create property access node. 2114 // Create property access node.
2116 lhs = new AccessNode(source, callToken, finish, lhs, property); 2115 lhs = new AccessNode(callToken, finish, lhs, property);
2117 2116
2118 break; 2117 break;
2119 2118
2120 default: 2119 default:
2121 break loop; 2120 break loop;
2167 2166
2168 if (!env._no_syntax_extensions && type == LBRACE) { 2167 if (!env._no_syntax_extensions && type == LBRACE) {
2169 arguments.add(objectLiteral()); 2168 arguments.add(objectLiteral());
2170 } 2169 }
2171 2170
2172 final CallNode callNode = new CallNode(source, constructor.getToken(), finish, constructor, arguments); 2171 final CallNode callNode = new CallNode(constructor.getToken(), finish, constructor, arguments);
2173 2172
2174 return new UnaryNode(source, newToken, callNode); 2173 return new UnaryNode(newToken, callNode);
2175 } 2174 }
2176 2175
2177 /** 2176 /**
2178 * MemberExpression : 2177 * MemberExpression :
2179 * PrimaryExpression 2178 * PrimaryExpression
2221 final Node index = expression(); 2220 final Node index = expression();
2222 2221
2223 expect(RBRACKET); 2222 expect(RBRACKET);
2224 2223
2225 // Create indexing node. 2224 // Create indexing node.
2226 lhs = new IndexNode(source, callToken, finish, lhs, index); 2225 lhs = new IndexNode(callToken, finish, lhs, index);
2227 2226
2228 break; 2227 break;
2229 2228
2230 case PERIOD: 2229 case PERIOD:
2231 if (lhs == null) { 2230 if (lhs == null) {
2235 next(); 2234 next();
2236 2235
2237 final IdentNode property = getIdentifierName(); 2236 final IdentNode property = getIdentifierName();
2238 2237
2239 // Create property access node. 2238 // Create property access node.
2240 lhs = new AccessNode(source, callToken, finish, lhs, property); 2239 lhs = new AccessNode(callToken, finish, lhs, property);
2241 2240
2242 break; 2241 break;
2243 2242
2244 default: 2243 default:
2245 break loop; 2244 break loop;
2324 2323
2325 // name is null, generate anonymous name 2324 // name is null, generate anonymous name
2326 boolean isAnonymous = false; 2325 boolean isAnonymous = false;
2327 if (name == null) { 2326 if (name == null) {
2328 final String tmpName = "_L" + source.getLine(Token.descPosition(token)); 2327 final String tmpName = "_L" + source.getLine(Token.descPosition(token));
2329 name = new IdentNode(source, functionToken, Token.descPosition(functionToken), tmpName); 2328 name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
2330 isAnonymous = true; 2329 isAnonymous = true;
2331 } 2330 }
2332 2331
2333 expect(LPAREN); 2332 expect(LPAREN);
2334 final List<IdentNode> parameters = formalParameterList(); 2333 final List<IdentNode> parameters = formalParameterList();
2375 throw error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken()); 2374 throw error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken());
2376 } 2375 }
2377 // rename in non-strict mode 2376 // rename in non-strict mode
2378 parameterName = functionNode.uniqueName(parameterName); 2377 parameterName = functionNode.uniqueName(parameterName);
2379 final long parameterToken = parameter.getToken(); 2378 final long parameterToken = parameter.getToken();
2380 parameters.set(i, new IdentNode(source, parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName))); 2379 parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
2381 } 2380 }
2382 2381
2383 parametersSet.add(parameterName); 2382 parametersSet.add(parameterName);
2384 } 2383 }
2385 } else if (arity == 1) { 2384 } else if (arity == 1) {
2387 functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); 2386 functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS);
2388 } 2387 }
2389 } 2388 }
2390 2389
2391 if (isStatement) { 2390 if (isStatement) {
2392 final VarNode varNode = new VarNode(source, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT); 2391 final VarNode varNode = new VarNode(functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
2393 if (topLevel) { 2392 if (topLevel) {
2394 functionDeclarations.add(lineNumber); 2393 functionDeclarations.add(lineNumber);
2395 functionDeclarations.add(varNode); 2394 functionDeclarations.add(varNode);
2396 } else { 2395 } else {
2397 appendStatement(lineNumber); 2396 appendStatement(lineNumber);
2467 // just expression as function body 2466 // just expression as function body
2468 final Node expr = expression(); 2467 final Node expr = expression();
2469 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode); 2468 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
2470 // create a return statement - this creates code in itself and does not need to be 2469 // create a return statement - this creates code in itself and does not need to be
2471 // wrapped into an ExecuteNode 2470 // wrapped into an ExecuteNode
2472 final ReturnNode returnNode = new ReturnNode(source, expr.getToken(), finish, expr); 2471 final ReturnNode returnNode = new ReturnNode(expr.getToken(), finish, expr);
2473 appendStatement(returnNode); 2472 appendStatement(returnNode);
2474 lastToken = token; 2473 lastToken = token;
2475 functionNode.setFinish(Token.descPosition(token) + Token.descLength(token)); 2474 functionNode.setFinish(Token.descPosition(token) + Token.descLength(token));
2476 2475
2477 } else { 2476 } else {
2509 } 2508 }
2510 prependStatement(decl); 2509 prependStatement(decl);
2511 } 2510 }
2512 } 2511 }
2513 2512
2514 private RuntimeNode referenceError(final Node lhs, final Node rhs) { 2513 private static RuntimeNode referenceError(final Node lhs, final Node rhs) {
2515 final ArrayList<Node> args = new ArrayList<>(); 2514 final ArrayList<Node> args = new ArrayList<>();
2516 args.add(lhs); 2515 args.add(lhs);
2517 if (rhs == null) { 2516 if (rhs == null) {
2518 args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish())); 2517 args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
2519 } else { 2518 } else {
2520 args.add(rhs); 2519 args.add(rhs);
2521 } 2520 }
2522 args.add(LiteralNode.newInstance(source, lhs.getToken(), lhs.getFinish(), lhs.toString())); 2521 args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish(), lhs.toString()));
2523 return new RuntimeNode(source, lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args); 2522 return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
2524 } 2523 }
2525 2524
2526 /* 2525 /*
2527 * parse LHS [a, b, ..., c]. 2526 * parse LHS [a, b, ..., c].
2528 * 2527 *
2568 case SUB: 2567 case SUB:
2569 case BIT_NOT: 2568 case BIT_NOT:
2570 case NOT: 2569 case NOT:
2571 next(); 2570 next();
2572 final Node expr = unaryExpression(); 2571 final Node expr = unaryExpression();
2573 return new UnaryNode(source, unaryToken, expr); 2572 return new UnaryNode(unaryToken, expr);
2574 2573
2575 case INCPREFIX: 2574 case INCPREFIX:
2576 case DECPREFIX: 2575 case DECPREFIX:
2577 final TokenType opType = type; 2576 final TokenType opType = type;
2578 next(); 2577 next();
2757 2756
2758 // Fail expression. 2757 // Fail expression.
2759 final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn); 2758 final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
2760 2759
2761 // Build up node. 2760 // Build up node.
2762 lhs = new TernaryNode(source, op, lhs, rhs, third); 2761 lhs = new TernaryNode(op, lhs, rhs, third);
2763 } else { 2762 } else {
2764 // Skip operator. 2763 // Skip operator.
2765 next(); 2764 next();
2766 2765
2767 // Get the next primary expression. 2766 // Get the next primary expression.
2818 /** 2817 /**
2819 * Add a line number node at current position 2818 * Add a line number node at current position
2820 */ 2819 */
2821 private LineNumberNode lineNumber() { 2820 private LineNumberNode lineNumber() {
2822 if (env._debug_lines) { 2821 if (env._debug_lines) {
2823 return new LineNumberNode(source, token, line); 2822 return new LineNumberNode(token, line);
2824 } 2823 }
2825 return null; 2824 return null;
2826 } 2825 }
2827 2826
2828 @Override 2827 @Override

mercurial