Changeset 185989 in webkit
- Timestamp:
- Jun 25, 2015 11:49:20 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 27 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r185976 r185989 1 2015-06-26 Aleksandr Skachkov <gskachkov@gmail.com> 2 3 [ES6] Implement ES6 arrow function syntax. Parser of arrow function with execution as common function 4 https://bugs.webkit.org/show_bug.cgi?id=144955 5 6 Reviewed by Yusuke Suzuki. 7 8 Added arrow function tests 9 10 * js/arrowfunction-asparamter-1-expected.txt: Added. 11 * js/arrowfunction-asparamter-1.html: Added. 12 * js/arrowfunction-asparamter-2-expected.txt: Added. 13 * js/arrowfunction-asparamter-2.html: Added. 14 * js/arrowfunction-associativity-1-expected.txt: Added. 15 * js/arrowfunction-associativity-1.html: Added. 16 * js/arrowfunction-associativity-2-expected.txt: Added. 17 * js/arrowfunction-associativity-2.html: Added. 18 * js/arrowfunction-block-1-expected.txt: Added. 19 * js/arrowfunction-block-1.html: Added. 20 * js/arrowfunction-block-2-expected.txt: Added. 21 * js/arrowfunction-block-2.html: Added. 22 * js/arrowfunction-syntax-endings-expected.txt: Added. 23 * js/arrowfunction-syntax-endings.html: Added. 24 * js/arrowfunction-syntax-errors-expected.txt: Added. 25 * js/arrowfunction-syntax-errors.html: Added. 26 * js/arrowfunction-syntax-expected.txt: Added. 27 * js/arrowfunction-syntax.html: Added. 28 * js/script-tests/arrowfunction-asparamter-1.js: Added. 29 * js/script-tests/arrowfunction-asparamter-2.js: Added. 30 * js/script-tests/arrowfunction-associativity-1.js: Added. 31 * js/script-tests/arrowfunction-associativity-2.js: Added. 32 * js/script-tests/arrowfunction-block-1.js: Added. 33 * js/script-tests/arrowfunction-block-2.js: Added. 34 * js/script-tests/arrowfunction-syntax-endings.js: Added. 35 * js/script-tests/arrowfunction-syntax-errors.js: Added. 36 * js/script-tests/arrowfunction-syntax.js: Added. 37 1 38 2015-06-25 Chris Fleizach <cfleizach@apple.com> 2 39 -
trunk/Source/JavaScriptCore/ChangeLog
r185981 r185989 1 2015-06-26 Aleksandr Skachkov <gskachkov@gmail.com> 2 3 [ES6] Implement ES6 arrow function syntax. Parser of arrow function with execution as common function. 4 https://bugs.webkit.org/show_bug.cgi?id=144955 5 6 Reviewed by Yusuke Suzuki. 7 8 Added support of ES6 arrow function. Changes were made according to following spec http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax. Patch does not include any arrow function specific behavior e.g. lexical bind this, arguments and etc. 9 This patch implements the simplest cases of arrow function declaration: 10 parameters () => 10 + 20 11 parameter x => x + 20 12 parameters (x, y) => x + y 13 function with block x => { return x*10; } 14 15 Not implemented: 16 bind of the this, arguments, super and etc. 17 exception in case of trying to use 'new' with arrow function 18 19 * parser/ASTBuilder.h: 20 (JSC::ASTBuilder::createFunctionExpr): 21 (JSC::ASTBuilder::createArrowFunctionExpr): 22 (JSC::ASTBuilder::createGetterOrSetterProperty): 23 (JSC::ASTBuilder::createFuncDeclStatement): 24 * parser/Lexer.cpp: 25 (JSC::Lexer<T>::setTokenPosition): 26 (JSC::Lexer<T>::lex): 27 * parser/Lexer.h: 28 (JSC::Lexer::lastTokenLocation): 29 (JSC::Lexer::setTerminator): 30 * parser/Parser.cpp: 31 (JSC::Parser<LexerType>::parseInner): 32 (JSC::Parser<LexerType>::parseSourceElements): 33 (JSC::Parser<LexerType>::parseArrowFunctionSingleExpressionBody): 34 (JSC::Parser<LexerType>::parseSwitchClauses): 35 (JSC::Parser<LexerType>::parseSwitchDefaultClause): 36 (JSC::Parser<LexerType>::parseBlockStatement): 37 (JSC::Parser<LexerType>::parseFunctionBody): 38 (JSC::stringForFunctionMode): 39 (JSC::Parser<LexerType>::parseFunctionParameters): 40 (JSC::Parser<LexerType>::parseFunctionInfo): 41 (JSC::Parser<LexerType>::parseFunctionDeclaration): 42 (JSC::Parser<LexerType>::parseClass): 43 (JSC::Parser<LexerType>::parseAssignmentExpression): 44 (JSC::Parser<LexerType>::parsePropertyMethod): 45 (JSC::Parser<LexerType>::parseGetterSetter): 46 (JSC::Parser<LexerType>::parseArrowFunctionExpression): 47 * parser/Parser.h: 48 (JSC::Parser::locationBeforeLastToken): 49 (JSC::Parser::isEndOfArrowFunction): 50 (JSC::Parser::isArrowFunctionParamters): 51 (JSC::Parser::setEndOfStatement): 52 * parser/ParserFunctionInfo.h: 53 * parser/ParserTokens.h: 54 * parser/SourceCode.h: 55 (JSC::SourceCode::subArrowExpression): 56 * parser/SourceProviderCacheItem.h: 57 (JSC::SourceProviderCacheItem::endFunctionToken): 58 (JSC::SourceProviderCacheItem::SourceProviderCacheItem): 59 * parser/SyntaxChecker.h: 60 (JSC::SyntaxChecker::createArrowFunctionExpr): 61 (JSC::SyntaxChecker::setFunctionNameStart): 62 1 63 2015-06-25 Yusuke Suzuki <utatane.tea@gmail.com> 2 64 -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r185981 r185989 348 348 { 349 349 FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body, 350 m_sourceCode->subExpression(info. openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);350 m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters); 351 351 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset); 352 352 return result; … … 365 365 } 366 366 367 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 368 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& info) 369 { 370 SourceCode source = info.functionBodyType == ArrowFunctionBodyExpression 371 ? m_sourceCode->subArrowExpression(info.arrowFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn) 372 : m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn); 373 374 FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *info.name, info.body, source, info.parameters); 375 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset); 376 return result; 377 } 378 #endif 379 367 380 NEVER_INLINE PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, bool, 368 381 const Identifier* name, const ParserFunctionInfo<ASTBuilder>& info, SuperBinding superBinding) … … 371 384 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset); 372 385 info.body->setInferredName(*name); 373 SourceCode source = m_sourceCode->subExpression(info. openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn);386 SourceCode source = m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn); 374 387 FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, info.body, source, info.parameters); 375 388 return new (m_parserArena) PropertyNode(*name, funcExpr, type, PropertyNode::Unknown, superBinding); … … 381 394 info.body->setLoc(info.bodyStartLine, info.bodyEndLine, location.startOffset, location.lineStartOffset); 382 395 const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name); 383 SourceCode source = m_sourceCode->subExpression(info. openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn);396 SourceCode source = m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn); 384 397 FuncExprNode* funcExpr = new (m_parserArena) FuncExprNode(location, vm->propertyNames->nullIdentifier, info.body, source, info.parameters); 385 398 return new (m_parserArena) PropertyNode(ident, funcExpr, type, PropertyNode::Unknown, superBinding); … … 418 431 { 419 432 FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *info.name, info.body, 420 m_sourceCode->subExpression(info. openBraceOffset, info.closeBraceOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters);433 m_sourceCode->subExpression(info.startFunctionOffset, info.endFunctionOffset, info.bodyStartLine, info.bodyStartColumn), info.parameters); 421 434 if (*info.name == m_vm->propertyNames->arguments) 422 435 usesArguments(); -
trunk/Source/JavaScriptCore/parser/Lexer.cpp
r185437 r185989 1716 1716 } 1717 1717 1718 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1719 template <typename T> 1720 void Lexer<T>::setTokenPosition(JSToken* tokenRecord) 1721 { 1722 JSTokenData* tokenData = &tokenRecord->m_data; 1723 tokenData->line = lineNumber(); 1724 tokenData->offset = currentOffset(); 1725 tokenData->lineStartOffset = currentLineStartOffset(); 1726 ASSERT(tokenData->offset >= tokenData->lineStartOffset); 1727 } 1728 #endif 1729 1718 1730 template <typename T> 1719 1731 JSTokenType Lexer<T>::lex(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode) … … 1721 1733 JSTokenData* tokenData = &tokenRecord->m_data; 1722 1734 JSTokenLocation* tokenLocation = &tokenRecord->m_location; 1735 m_lastTockenLocation = JSTokenLocation(tokenRecord->m_location); 1736 1723 1737 ASSERT(!m_error); 1724 1738 ASSERT(m_buffer8.isEmpty()); … … 1779 1793 token = GT; 1780 1794 break; 1781 case CharacterEqual: 1795 case CharacterEqual: { 1796 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1797 if (peek(1) == '>') { 1798 token = ARROWFUNCTION; 1799 tokenData->line = lineNumber(); 1800 tokenData->offset = currentOffset(); 1801 tokenData->lineStartOffset = currentLineStartOffset(); 1802 ASSERT(tokenData->offset >= tokenData->lineStartOffset); 1803 shift(); 1804 shift(); 1805 break; 1806 } 1807 #endif 1782 1808 shift(); 1783 1809 if (m_current == '=') { … … 1793 1819 token = EQUAL; 1794 1820 break; 1821 } 1795 1822 case CharacterLess: 1796 1823 shift(); -
trunk/Source/JavaScriptCore/parser/Lexer.h
r184337 r185989 88 88 bool isReparsing() const { return m_isReparsing; } 89 89 90 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 91 void setTokenPosition(JSToken* tokenRecord); 92 #endif 90 93 JSTokenType lex(JSToken*, unsigned, bool strictMode); 91 94 bool nextTokenIsColon(); … … 98 101 } 99 102 JSTextPosition positionBeforeLastNewline() const { return m_positionBeforeLastNewline; } 103 JSTokenLocation lastTokenLocation() const { return m_lastTockenLocation; } 100 104 void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; } 101 105 int lastLineNumber() const { return m_lastLineNumber; } … … 131 135 { 132 136 m_lineNumber = line; 137 } 138 void setTerminator(bool terminator) 139 { 140 m_terminator = terminator; 133 141 } 134 142 … … 216 224 const T* m_lineStart; 217 225 JSTextPosition m_positionBeforeLastNewline; 226 JSTokenLocation m_lastTockenLocation; 218 227 bool m_isReparsing; 219 228 bool m_atLineStart; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r185981 r185989 265 265 m_statementDepth--; 266 266 ScopeRef scope = currentScope(); 267 SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode );267 SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode, StandardFunctionParseType); 268 268 if (!sourceElements || !consume(EOFTOK)) { 269 269 if (hasError()) … … 344 344 345 345 template <typename LexerType> 346 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode )346 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode, FunctionParseType functionParseType) 347 347 { 348 348 const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length … … 353 353 auto savePoint = createSavePoint(); 354 354 bool hasSetStrict = false; 355 356 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 357 if (match(ARROWFUNCTION)) { 358 TreeStatement arrowfunctionStatement = parseArrowFunctionSingleExpressionBody(context, functionParseType); 359 360 if (arrowfunctionStatement) { 361 context.setEndOffset(arrowfunctionStatement, m_lastTokenEndPosition.offset); 362 context.appendStatement(sourceElements, arrowfunctionStatement); 363 } 364 365 propagateError(); 366 return sourceElements; 367 } 368 #endif 369 355 370 while (TreeStatement statement = parseStatement(context, directive, &directiveLiteralLength)) { 356 371 if (mode == CheckForStrictMode && !seenNonDirective) { … … 583 598 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition); 584 599 } 600 601 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 602 template <typename LexerType> 603 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseArrowFunctionSingleExpressionBody(TreeBuilder& context, FunctionParseType parseType) 604 { 605 ASSERT(match(ARROWFUNCTION)); 606 607 // When reparsing phase, parseType becomes StandardFunctionParseType even if the function is arrow function. 608 // This condition considers the following situations. 609 // (1): If we are in the reparsing phase, this arrow function is already parsed once, so there is no syntax error. 610 // (2): But if we are not in the reparsing phase, we should check this function is called in the context of the arrow function. 611 if (!m_lexer->isReparsing() && parseType != ArrowFunctionParseType) 612 failDueToUnexpectedToken(); 613 614 JSTokenLocation location(tokenLocation()); 615 JSTextPosition start = tokenStartPosition(); 616 JSTextPosition end = tokenEndPosition(); 617 618 next(); 619 620 failIfStackOverflow(); 621 TreeExpression expr = parseAssignmentExpression(context); 622 failIfFalse(expr, "Cannot parse the arrow function expression"); 623 624 context.setEndOffset(expr, m_lastTokenEndPosition.offset); 625 626 failIfFalse(isEndOfArrowFunction(), "Expected a ';', ']', '}', ')', ',', line terminator or EOF following a arrow function statement"); 627 628 end = tokenEndPosition(); 629 630 if (!m_lexer->prevTerminator()) 631 setEndOfStatement(); 632 633 return context.createReturnStatement(location, expr, start, end); 634 } 635 #endif 585 636 586 637 template <typename LexerType> … … 1066 1117 failIfFalse(condition, "Cannot parse switch clause"); 1067 1118 consumeOrFail(COLON, "Expected a ':' after switch clause expression"); 1068 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode );1119 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType); 1069 1120 failIfFalse(statements, "Cannot parse the body of a switch clause"); 1070 1121 TreeClause clause = context.createClause(condition, statements); … … 1079 1130 failIfFalse(condition, "Cannot parse switch case expression"); 1080 1131 consumeOrFail(COLON, "Expected a ':' after switch clause expression"); 1081 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode );1132 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType); 1082 1133 failIfFalse(statements, "Cannot parse the body of a switch clause"); 1083 1134 clause = context.createClause(condition, statements); … … 1096 1147 next(); 1097 1148 consumeOrFail(COLON, "Expected a ':' after switch default clause"); 1098 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode );1149 TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType); 1099 1150 failIfFalse(statements, "Cannot parse the body of a switch default clause"); 1100 1151 TreeClause result = context.createClause(0, statements); … … 1181 1232 return result; 1182 1233 } 1183 TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode );1234 TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode, StandardFunctionParseType); 1184 1235 failIfFalse(subtree, "Cannot parse the body of the block statement"); 1185 1236 matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement"); … … 1202 1253 TreeStatement result = 0; 1203 1254 bool shouldSetEndOffset = true; 1255 1204 1256 switch (m_token.m_type) { 1205 1257 case OPENBRACE: … … 1311 1363 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody( 1312 1364 TreeBuilder& context, int functionKeywordStart, int functionNameStart, 1313 int parametersStart, ConstructorKind constructorKind )1365 int parametersStart, ConstructorKind constructorKind, FunctionParseType parseType) 1314 1366 { 1315 1367 JSTokenLocation startLocation(tokenLocation()); 1316 1368 unsigned startColumn = tokenColumn(); 1317 next(); 1318 1319 if (match(CLOSEBRACE)) { 1320 unsigned endColumn = tokenColumn(); 1321 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind); 1322 } 1369 1370 if (parseType == StandardFunctionParseType) { 1371 next(); 1372 if (match(CLOSEBRACE)) { 1373 unsigned endColumn = tokenColumn(); 1374 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind); 1375 } 1376 } 1377 1323 1378 DepthManager statementDepth(&m_statementDepth); 1324 1379 m_statementDepth = 0; 1325 1380 typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<VM*>(m_vm), m_lexer.get()); 1326 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode), "Cannot parse body of this function"); 1381 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1382 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, parseType), parseType == StandardFunctionParseType ? "Cannot parse body of this function" : "Cannot parse body of this arrow function"); 1383 #else 1384 failIfFalse(parseSourceElements(bodyBuilder, CheckForStrictMode, StandardFunctionParseType), "Cannot parse body of this function"); 1385 #endif 1327 1386 unsigned endColumn = tokenColumn(); 1328 1387 return context.createFunctionBody(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind); … … 1340 1399 case MethodMode: 1341 1400 return "method"; 1401 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1402 case ArrowFunctionMode: 1403 return "arrow function"; 1404 #endif 1342 1405 } 1343 1406 RELEASE_ASSERT_NOT_REACHED(); … … 1345 1408 } 1346 1409 1347 template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, AutoPopScopeRef& functionScope, ParserFunctionInfo<TreeBuilder>& info) 1348 { 1349 if (match(IDENT)) { 1350 info.name = m_token.m_data.ident; 1351 m_lastFunctionName = info.name; 1352 next(); 1353 if (!nameIsInContainingScope) 1354 failIfFalseIfStrict(functionScope->declareVariable(info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 1355 } else if (requirements == FunctionNeedsName) { 1356 if (match(OPENPAREN) && mode == FunctionMode) 1357 semanticFail("Function statements must have a name"); 1358 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 1359 failDueToUnexpectedToken(); 1360 return false; 1361 } 1410 template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, FunctionParseMode mode, ParserFunctionInfo<TreeBuilder>& info) 1411 { 1362 1412 int parametersStart = m_token.m_location.startOffset; 1413 1414 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1415 if (mode == ArrowFunctionMode) { 1416 if (!match(IDENT) && !match(OPENPAREN)) { 1417 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 1418 failWithMessage("Expected an arrow function input parameter"); 1419 } else { 1420 if (match(OPENPAREN)) { 1421 next(); 1422 1423 if (!match(CLOSEPAREN)) { 1424 info.parameters = parseFormalParameters(context); 1425 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1426 } 1427 1428 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration"); 1429 } else { 1430 auto parameter = parseDeconstructionPattern(context, DeconstructToParameters); 1431 failIfFalse(parameter, "Cannot parse parameter pattern"); 1432 info.parameters = context.createFormalParameterList(parameter); 1433 failIfFalse(info.parameters, "Cannot parse parameters for this ", stringForFunctionMode(mode)); 1434 } 1435 } 1436 1437 return parametersStart; 1438 } 1439 #endif 1440 1363 1441 if (!consume(OPENPAREN)) { 1364 1442 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); … … 1385 1463 return parametersStart; 1386 1464 } 1387 1388 template <typename LexerType> 1389 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& info )1465 1466 template <typename LexerType> 1467 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, FunctionParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& info, FunctionParseType parseType) 1390 1468 { 1391 1469 AutoPopScopeRef functionScope(this, pushScope()); … … 1394 1472 const Identifier* lastFunctionName = m_lastFunctionName; 1395 1473 m_lastFunctionName = nullptr; 1396 1397 int parametersStart = parseFunctionParameters(context, requirements, mode, nameIsInContainingScope, functionScope, info); 1398 propagateError(); 1399 1400 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); 1401 1402 // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed. 1403 // Set ConstructorKind to None for non-constructor methods of classes. 1404 if (m_defaultConstructorKind != ConstructorKind::None) { 1405 constructorKind = m_defaultConstructorKind; 1406 expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded; 1407 } 1474 int parametersStart; 1475 1476 switch (parseType) { 1477 case StandardFunctionParseType: { 1478 if (match(IDENT)) { 1479 info.name = m_token.m_data.ident; 1480 m_lastFunctionName = info.name; 1481 next(); 1482 if (!nameIsInContainingScope) 1483 failIfFalseIfStrict(functionScope->declareVariable(info.name), "'", info.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 1484 } else if (requirements == FunctionNeedsName) { 1485 if (match(OPENPAREN) && mode == FunctionMode) 1486 semanticFail("Function statements must have a name"); 1487 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 1488 failDueToUnexpectedToken(); 1489 return false; 1490 } 1491 1492 parametersStart = parseFunctionParameters(context, mode, info); 1493 propagateError(); 1494 1495 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); 1496 1497 // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed. 1498 // Set ConstructorKind to None for non-constructor methods of classes. 1499 1500 if (m_defaultConstructorKind != ConstructorKind::None) { 1501 constructorKind = m_defaultConstructorKind; 1502 expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded; 1503 } 1504 1505 info.startFunctionOffset = m_token.m_data.offset; 1506 1507 break; 1508 } 1509 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1510 case ArrowFunctionParseType: { 1511 parametersStart = parseFunctionParameters(context, ArrowFunctionMode, info); 1512 propagateError(); 1513 1514 matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration"); 1515 ASSERT(constructorKind == ConstructorKind::None); 1516 1517 info.arrowFunctionOffset = m_token.m_data.offset; 1518 // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function 1519 // and we need use common approach to parse function body 1520 SavePoint savePoint = createSavePoint(); 1521 1522 next(); 1523 info.functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression; 1524 info.startFunctionOffset = (info.functionBodyType == ArrowFunctionBodyBlock) ? m_token.m_data.offset : info.arrowFunctionOffset; 1525 1526 restoreSavePoint(savePoint); 1527 1528 break; 1529 } 1530 #endif 1531 } 1532 1408 1533 bool isClassConstructor = constructorKind != ConstructorKind::None; 1409 1534 1410 info.openBraceOffset = m_token.m_data.offset;1411 1535 info.bodyStartLine = tokenLine(); 1412 1536 info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset; … … 1414 1538 1415 1539 // If we know about this function already, we can use the cached info and skip the parser to the end of the function. 1416 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(info. openBraceOffset) : 0) {1540 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(info.startFunctionOffset) : 0) { 1417 1541 // If we're in a strict context, the cached function info must say it was strict too. 1418 1542 ASSERT(!strictMode() || cachedInfo->strictMode); 1419 1543 JSTokenLocation endLocation; 1420 1544 1421 endLocation.line = cachedInfo-> closeBraceLine;1422 endLocation.startOffset = cachedInfo-> closeBraceOffset;1423 endLocation.lineStartOffset = cachedInfo-> closeBraceLineStartOffset;1545 endLocation.line = cachedInfo->lastTockenLine; 1546 endLocation.startOffset = cachedInfo->lastTockenStartOffset; 1547 endLocation.lineStartOffset = cachedInfo->lastTockenLineStartOffset; 1424 1548 1425 1549 bool endColumnIsOnStartLine = (endLocation.line == info.bodyStartLine); … … 1438 1562 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error"); 1439 1563 1440 info.closeBraceOffset = cachedInfo->closeBraceOffset; 1441 1442 m_token = cachedInfo->closeBraceToken(); 1564 m_token = cachedInfo->endFunctionToken(); 1565 1443 1566 if (endColumnIsOnStartLine) 1444 1567 m_token.m_location.lineStartOffset = currentLineStartOffset; … … 1446 1569 m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset); 1447 1570 m_lexer->setLineNumber(m_token.m_location.line); 1448 1571 info.endFunctionOffset = cachedInfo->endFunctionOffset; 1572 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1573 if (parseType == ArrowFunctionParseType) 1574 info.functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock; 1575 else 1576 info.functionBodyType = StandardFunctionBodyBlock; 1577 1578 switch (info.functionBodyType) { 1579 case ArrowFunctionBodyExpression: 1580 next(); 1581 context.setEndOffset(info.body, m_lexer->currentOffset()); 1582 break; 1583 case ArrowFunctionBodyBlock: 1584 case StandardFunctionBodyBlock: 1585 context.setEndOffset(info.body, m_lexer->currentOffset()); 1586 next(); 1587 break; 1588 } 1589 #else 1449 1590 context.setEndOffset(info.body, m_lexer->currentOffset()); 1450 1451 next(); 1591 next(); 1592 #endif 1452 1593 info.bodyEndLine = m_lastTokenEndPosition.line; 1453 1594 return true; 1454 1595 } 1596 1455 1597 m_lastFunctionName = lastFunctionName; 1456 1598 ParserState oldState = saveState(); 1457 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind); 1599 1600 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1601 switch (info.functionBodyType) { 1602 case ArrowFunctionBodyBlock: { 1603 // Consume => in case of arrow function block e.g. x => { return x; } 1604 next(); 1605 1606 info.bodyStartLine = tokenLine(); 1607 info.bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset; 1608 1609 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType); 1610 break; 1611 } 1612 case StandardFunctionBodyBlock: 1613 case ArrowFunctionBodyExpression : { 1614 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, parseType); 1615 break; 1616 } 1617 } 1618 #else 1619 info.body = parseFunctionBody(context, functionKeywordStart, functionNameStart, parametersStart, constructorKind, StandardFunctionParseType); 1620 #endif 1621 1458 1622 restoreState(oldState); 1459 1623 failIfFalse(info.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); … … 1471 1635 semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class"); 1472 1636 1473 info.closeBraceOffset = m_token.m_data.offset; 1474 unsigned closeBraceLine = m_token.m_data.line; 1475 unsigned closeBraceLineStartOffset = m_token.m_data.lineStartOffset; 1637 JSTokenLocation location = JSTokenLocation(m_token.m_location); 1638 info.endFunctionOffset = m_token.m_data.offset; 1639 1640 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1641 if (info.functionBodyType == ArrowFunctionBodyExpression) { 1642 location = locationBeforeLastToken(); 1643 info.endFunctionOffset = location.endOffset; 1644 } 1645 #endif 1476 1646 1477 1647 // Cache the tokenizer state and the function scope the first time the function is parsed. … … 1479 1649 static const int minimumFunctionLengthToCache = 16; 1480 1650 std::unique_ptr<SourceProviderCacheItem> newInfo; 1481 int functionLength = info. closeBraceOffset - info.openBraceOffset;1651 int functionLength = info.endFunctionOffset - info.startFunctionOffset; 1482 1652 if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) { 1483 1653 SourceProviderCacheItemCreationParameters parameters; 1654 parameters.endFunctionOffset = info.endFunctionOffset; 1484 1655 parameters.functionNameStart = functionNameStart; 1485 parameters.closeBraceLine = closeBraceLine; 1486 parameters.closeBraceOffset = info.closeBraceOffset; 1487 parameters.closeBraceLineStartOffset = closeBraceLineStartOffset; 1656 parameters.lastTockenLine = location.line; 1657 parameters.lastTockenStartOffset = location.startOffset; 1658 parameters.lastTockenEndOffset = location.endOffset; 1659 parameters.lastTockenLineStartOffset = location.lineStartOffset; 1660 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1661 if (info.functionBodyType == ArrowFunctionBodyExpression) { 1662 parameters.isBodyArrowExpression = true; 1663 parameters.tokenType = m_token.m_type; 1664 } 1665 #endif 1488 1666 functionScope->fillParametersForSourceProviderCache(parameters); 1489 1667 newInfo = SourceProviderCacheItem::create(parameters); 1490 1491 1668 } 1492 1669 1493 1670 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error"); 1671 1672 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1673 if (info.functionBodyType == ArrowFunctionBodyExpression) 1674 failIfFalse(isEndOfArrowFunction(), "Expected the closing ';' ',' ']' ')' '}', line terminator or EOF after arrow function"); 1675 else { 1676 matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body"); 1677 next(); 1678 } 1679 #else 1494 1680 matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body"); 1681 next(); 1682 #endif 1495 1683 1496 1684 if (newInfo) 1497 m_functionCache->add(info.openBraceOffset, WTF::move(newInfo)); 1498 1499 next(); 1685 m_functionCache->add(info.startFunctionOffset, WTF::move(newInfo)); 1686 1500 1687 info.bodyEndLine = m_lastTokenEndPosition.line; 1501 1688 return true; … … 1511 1698 ParserFunctionInfo<TreeBuilder> info; 1512 1699 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, 1513 functionKeywordStart, info )), "Cannot parse this function");1700 functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse this function"); 1514 1701 failIfFalse(info.name, "Function statements must have a name"); 1515 1702 failIfFalseIfStrict(declareVariable(info.name), "Cannot declare a function named '", info.name->impl(), "' in strict mode"); … … 1630 1817 ParserFunctionInfo<TreeBuilder> methodInfo; 1631 1818 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 1632 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? FunctionMode : MethodMode, false, 1633 isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo)), "Cannot parse this method"); 1819 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? FunctionMode : MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 1634 1820 failIfFalse(ident && declareVariable(ident), "Cannot declare a method named '", methodInfo.name->impl(), "'"); 1635 1821 methodInfo.name = isConstructor ? className : ident; … … 1872 2058 } 1873 2059 2060 1874 2061 template <typename LexerType> 1875 2062 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context) … … 1890 2077 restoreSavePoint(savePoint); 1891 2078 } 2079 2080 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 2081 if (isArrowFunctionParamters()) 2082 return parseArrowFunctionExpression(context); 2083 #endif 2084 1892 2085 TreeExpression lhs = parseConditionalExpression(context); 1893 2086 failIfFalse(lhs, "Cannot parse expression"); … … 2130 2323 unsigned methodStart = tokenStart(); 2131 2324 ParserFunctionInfo<TreeBuilder> methodInfo; 2132 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::None, SuperBinding::NotNeeded, 2133 methodStart, methodInfo)), "Cannot parse this method"); 2325 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 2134 2326 methodInfo.name = methodName; 2135 2327 return context.createFunctionExpr(methodLocation, methodInfo); … … 2158 2350 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 2159 2351 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, constructorKind, superBinding, 2160 getterOrSetterStartOffset, info )), "Cannot parse getter definition");2352 getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse getter definition"); 2161 2353 } else { 2162 2354 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 2163 2355 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, constructorKind, superBinding, 2164 getterOrSetterStartOffset, info )), "Cannot parse setter definition");2356 getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse setter definition"); 2165 2357 } 2166 2358 if (stringPropertyName) … … 2429 2621 ParserFunctionInfo<TreeBuilder> info; 2430 2622 info.name = &m_vm->propertyNames->nullIdentifier; 2431 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, 2432 functionKeywordStart, info)), "Cannot parse function expression"); 2623 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse function expression"); 2433 2624 return context.createFunctionExpr(location, info); 2434 2625 } … … 2669 2860 return base; 2670 2861 } 2862 2863 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 2864 template <typename LexerType> 2865 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context) 2866 { 2867 JSTokenLocation location; 2868 2869 unsigned functionKeywordStart = tokenStart(); 2870 location = tokenLocation(); 2871 ParserFunctionInfo<TreeBuilder> info; 2872 info.name = &m_vm->propertyNames->nullIdentifier; 2873 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, ArrowFunctionParseType)), "Cannot parse arrow function expression"); 2874 2875 return context.createArrowFunctionExpr(location, info); 2876 } 2877 #endif 2671 2878 2672 2879 static const char* operatorString(bool prefix, unsigned tok) -
trunk/Source/JavaScriptCore/parser/Parser.h
r185699 r185989 81 81 82 82 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode }; 83 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 84 enum FunctionParseType { StandardFunctionParseType, ArrowFunctionParseType }; 85 #else 86 enum FunctionParseType { StandardFunctionParseType}; 87 #endif 83 88 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName }; 84 89 enum FunctionParseMode { … … 87 92 SetterMode, 88 93 MethodMode, 94 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 95 ArrowFunctionMode 96 #endif 89 97 }; 90 98 enum DeconstructionKind { … … 431 439 432 440 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); } 441 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); } 433 442 Vector<RefPtr<UniquedStringImpl>>&& closedVariables() { return WTF::move(m_closedVariables); } 434 443 … … 612 621 return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of; 613 622 } 623 624 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 625 ALWAYS_INLINE bool isEndOfArrowFunction() 626 { 627 return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator(); 628 } 629 630 ALWAYS_INLINE bool isArrowFunctionParamters() 631 { 632 bool isArrowFunction = false; 633 634 if (match(EOFTOK)) 635 return isArrowFunction; 636 637 SavePoint saveArrowFunctionPoint = createSavePoint(); 638 639 if (consume(OPENPAREN)) { 640 bool isArrowFunctionParamters = true; 641 642 while (consume(IDENT)) { 643 if (consume(COMMA)) { 644 if (!match(IDENT)) { 645 isArrowFunctionParamters = false; 646 break; 647 } 648 } else 649 break; 650 } 651 652 if (isArrowFunctionParamters) { 653 if (consume(CLOSEPAREN) && match(ARROWFUNCTION)) 654 isArrowFunction = true; 655 } 656 } else if (consume(IDENT) && match(ARROWFUNCTION)) 657 isArrowFunction = true; 658 659 restoreSavePoint(saveArrowFunctionPoint); 660 661 return isArrowFunction; 662 } 663 #endif 614 664 615 665 ALWAYS_INLINE unsigned tokenStart() … … 716 766 return result; 717 767 } 718 719 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode );768 769 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode, FunctionParseType); 720 770 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0); 721 771 #if ENABLE(ES6_CLASS_SYNTAX) … … 757 807 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName); 758 808 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded); 759 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind );809 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, FunctionParseType); 760 810 template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&); 761 811 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext }; … … 763 813 template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&); 764 814 815 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 816 template <class TreeBuilder> TreeStatement parseArrowFunctionSingleExpressionBody(TreeBuilder&, FunctionParseType); 817 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&); 818 #endif 819 765 820 template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, DeconstructionKind, const Identifier&, int depth, JSToken); 766 821 template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0); … … 768 823 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDeconstructionPattern(TreeBuilder&); 769 824 770 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& );771 772 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, Function Requirements, FunctionParseMode, bool, AutoPopScopeRef&, ParserFunctionInfo<TreeBuilder>&);825 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType); 826 827 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, FunctionParseMode, ParserFunctionInfo<TreeBuilder>&); 773 828 774 829 #if ENABLE(ES6_CLASS_SYNTAX) 775 830 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&); 776 831 #endif 832 777 833 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX) 778 834 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail); … … 794 850 } 795 851 852 853 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 854 void setEndOfStatement() 855 { 856 m_lexer->setTokenPosition(&m_token); 857 } 858 #endif 859 796 860 bool canRecurse() 797 861 { -
trunk/Source/JavaScriptCore/parser/ParserFunctionInfo.h
r181973 r185989 29 29 namespace JSC { 30 30 31 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 32 enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock }; 33 #endif 34 31 35 template <class TreeBuilder> 32 36 struct ParserFunctionInfo { … … 34 38 typename TreeBuilder::FormalParameterList parameters = 0; 35 39 typename TreeBuilder::FunctionBody body = 0; 36 unsigned openBraceOffset = 0;37 unsigned closeBraceOffset = 0;40 unsigned startFunctionOffset = 0; 41 unsigned endFunctionOffset = 0; 38 42 int bodyStartLine = 0; 39 43 int bodyEndLine = 0; 40 44 unsigned bodyStartColumn = 0; 45 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 46 unsigned arrowFunctionOffset = 0; 47 unsigned arrowFunctionNextTockenEndOffset = 0; 48 bool isArrowFunction { false }; 49 bool isEndByTerminator { false }; 50 FunctionBodyType functionBodyType { StandardFunctionBodyBlock }; 51 #endif 41 52 }; 42 53 -
trunk/Source/JavaScriptCore/parser/ParserTokens.h
r183373 r185989 76 76 DEBUGGER, 77 77 ELSE, 78 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 79 ARROWFUNCTION, 80 #endif 78 81 #if ENABLE(ES6_CLASS_SYNTAX) 79 82 CLASSTOKEN, -
trunk/Source/JavaScriptCore/parser/SourceCode.h
r182034 r185989 106 106 SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn); 107 107 108 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 109 SourceCode subArrowExpression(unsigned startArrowFunction, unsigned endArrowFunction, int firstLine, int startColumn); 110 #endif 108 111 private: 109 112 RefPtr<SourceProvider> m_provider; … … 118 121 return SourceCode(StringSourceProvider::create(source, url, startPosition), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt()); 119 122 } 123 124 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 125 inline SourceCode SourceCode::subArrowExpression(unsigned startArrowFunction, unsigned endArrowFunction, int firstLine, int startColumn) 126 { 127 ASSERT(provider()->source()[startArrowFunction] == '=' && provider()->source()[startArrowFunction + 1] == '>'); 128 129 startColumn += 1; // Convert to base 1. 130 return SourceCode(provider(), startArrowFunction, endArrowFunction, firstLine, startColumn); 131 } 132 #endif 120 133 121 134 inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn) -
trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
r184828 r185989 36 36 struct SourceProviderCacheItemCreationParameters { 37 37 unsigned functionNameStart; 38 unsigned closeBraceLine; 39 unsigned closeBraceOffset; 40 unsigned closeBraceLineStartOffset; 38 unsigned lastTockenLine; 39 unsigned lastTockenStartOffset; 40 unsigned lastTockenEndOffset; 41 unsigned lastTockenLineStartOffset; 42 unsigned endFunctionOffset; 41 43 bool needsFullActivation; 42 44 bool usesEval; … … 44 46 Vector<RefPtr<UniquedStringImpl>> usedVariables; 45 47 Vector<RefPtr<UniquedStringImpl>> writtenVariables; 48 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 49 bool isBodyArrowExpression { false }; 50 JSTokenType tokenType { CLOSEBRACE }; 51 #endif 46 52 }; 47 53 … … 57 63 ~SourceProviderCacheItem(); 58 64 59 JSToken closeBraceToken() const65 JSToken endFunctionToken() const 60 66 { 61 67 JSToken token; 68 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 69 token.m_type = isBodyArrowExpression ? tokenType : CLOSEBRACE; 70 #else 62 71 token.m_type = CLOSEBRACE; 63 token.m_data.offset = closeBraceOffset; 64 token.m_location.startOffset = closeBraceOffset; 65 token.m_location.endOffset = closeBraceOffset + 1; 66 token.m_location.line = closeBraceLine; 67 token.m_location.lineStartOffset = closeBraceLineStartOffset; 72 #endif 73 token.m_data.offset = lastTockenStartOffset; 74 token.m_location.startOffset = lastTockenStartOffset; 75 token.m_location.endOffset = lastTockenEndOffset; 76 token.m_location.line = lastTockenLine; 77 token.m_location.lineStartOffset = lastTockenLineStartOffset; 68 78 // token.m_location.sourceOffset is initialized once by the client. So, 69 79 // we do not need to set it here. … … 73 83 unsigned functionNameStart : 31; 74 84 bool needsFullActivation : 1; 85 86 unsigned endFunctionOffset : 31; 87 unsigned lastTockenLine : 31; 88 unsigned lastTockenStartOffset : 31; 89 unsigned lastTockenEndOffset: 31; 75 90 76 unsigned closeBraceLine : 31;77 91 bool usesEval : 1; 78 92 79 unsigned closeBraceOffset : 31;80 93 bool strictMode : 1; 81 94 82 unsigned closeBraceLineStartOffset;95 unsigned lastTockenLineStartOffset; 83 96 unsigned usedVariablesCount; 84 97 unsigned writtenVariablesCount; … … 86 99 UniquedStringImpl** usedVariables() const { return const_cast<UniquedStringImpl**>(m_variables); } 87 100 UniquedStringImpl** writtenVariables() const { return const_cast<UniquedStringImpl**>(&m_variables[usedVariablesCount]); } 101 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 102 bool isBodyArrowExpression; 103 JSTokenType tokenType; 104 #endif 88 105 89 106 private: … … 110 127 : functionNameStart(parameters.functionNameStart) 111 128 , needsFullActivation(parameters.needsFullActivation) 112 , closeBraceLine(parameters.closeBraceLine) 129 , endFunctionOffset(parameters.endFunctionOffset) 130 , lastTockenLine(parameters.lastTockenLine) 131 , lastTockenStartOffset(parameters.lastTockenStartOffset) 132 , lastTockenEndOffset(parameters.lastTockenEndOffset) 113 133 , usesEval(parameters.usesEval) 114 , closeBraceOffset(parameters.closeBraceOffset)115 134 , strictMode(parameters.strictMode) 116 , closeBraceLineStartOffset(parameters.closeBraceLineStartOffset)135 , lastTockenLineStartOffset(parameters.lastTockenLineStartOffset) 117 136 , usedVariablesCount(parameters.usedVariables.size()) 118 137 , writtenVariablesCount(parameters.writtenVariables.size()) 138 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 139 , isBodyArrowExpression(parameters.isBodyArrowExpression) 140 , tokenType(parameters.tokenType) 141 #endif 119 142 { 120 143 unsigned j = 0; -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r185981 r185989 180 180 ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; } 181 181 int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind) { return FunctionBodyResult; } 182 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 183 ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; } 184 #endif 185 void setFunctionNameStart(int, int) { } 182 186 int createArguments() { return ArgumentsResult; } 183 187 int createArguments(int) { return ArgumentsResult; }
Note: See TracChangeset
for help on using the changeset viewer.