Changeset 191875 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Nov 1, 2015, 9:46:17 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r191110 r191875 30 30 #include "Lexer.h" 31 31 #include "JSCInlines.h" 32 #include "SetForScope.h" 32 33 #include "SourceProvider.h" 33 34 #include "VM.h" … … 204 205 , m_statementDepth(0) 205 206 , m_nonTrivialExpressionCount(0) 207 , m_functionParsePhase(FunctionParsePhase::Body) 206 208 , m_lastIdentifier(0) 207 209 , m_lastFunctionName(nullptr) … … 218 220 m_token.m_location.lineStartOffset = source.startOffset(); 219 221 m_functionCache = vm->addSourceProviderCache(source.provider()); 222 220 223 ScopeRef scope = pushScope(); 221 if (isFunctionParseMode(parseMode)) 222 scope->setIsFunction(); 223 if (isModuleParseMode(parseMode)) 224 scope->setIsModule(); 224 scope->setSourceParseMode(parseMode); 225 225 226 if (strictMode == JSParserStrictMode::Strict) 226 227 scope->setStrictMode(); … … 242 243 ScopeRef scope = currentScope(); 243 244 scope->setIsLexicalScope(); 245 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Body); 244 246 245 247 bool isArrowFunctionBodyExpression = false; … … 474 476 SavePoint savePoint = createSavePoint(); 475 477 next(); 476 if (!match(IDENT) && !match(OPENBRACE) && !match(OPENBRACKET)) 478 // Intentionally use `match(IDENT) || match(LET) || match(YIELD)` and don't use `matchSpecIdentifier()`. 479 // We would like to fall into parseVariableDeclaration path even if "yield" is not treated as an Identifier. 480 // For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`. 481 // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration 482 // to raise consistent errors between "var", "const" and "let". 483 if (!(match(IDENT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET)) 477 484 shouldParseVariableDeclaration = false; 478 485 restoreSavePoint(savePoint); … … 586 593 declarations++; 587 594 bool hasInitializer = false; 588 if (match (IDENT) || isLETMaskedAsIDENT()) {595 if (matchSpecIdentifier()) { 589 596 failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 590 597 "Can't use 'let' as an identifier name for a LexicalDeclaration"); … … 835 842 TreeDestructuringPattern innerPattern = 0; 836 843 JSTokenLocation location = m_token.m_location; 837 if (match (IDENT) || isLETMaskedAsIDENT()) {844 if (matchSpecIdentifier()) { 838 845 failIfTrue(match(LET) && (kind == DestructureToLet || kind == DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 839 846 propertyName = m_token.m_data.ident; … … 892 899 893 900 default: { 894 if (!match (IDENT) && !isLETMaskedAsIDENT()) {901 if (!matchSpecIdentifier()) { 895 902 if (kind == DestructureToExpressions) 896 903 return 0; … … 1129 1136 return context.createBreakStatement(location, &m_vm->propertyNames->nullIdentifier, start, end); 1130 1137 } 1131 failIfFalse(match (IDENT) || isLETMaskedAsIDENT(), "Expected an identifier as the target for a break statement");1138 failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a break statement"); 1132 1139 const Identifier* ident = m_token.m_data.ident; 1133 1140 semanticFailIfFalse(getLabel(ident), "Cannot use the undeclared label '", ident->impl(), "'"); … … 1151 1158 return context.createContinueStatement(location, &m_vm->propertyNames->nullIdentifier, start, end); 1152 1159 } 1153 failIfFalse(match (IDENT) || isLETMaskedAsIDENT(), "Expected an identifier as the target for a continue statement");1160 failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a continue statement"); 1154 1161 const Identifier* ident = m_token.m_data.ident; 1155 1162 ScopeLabelInfo* label = getLabel(ident); … … 1333 1340 1334 1341 handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target"); 1335 if (! (match(IDENT) || isLETMaskedAsIDENT())) {1342 if (!matchSpecIdentifier()) { 1336 1343 semanticFailureDueToKeyword("catch variable name"); 1337 1344 failWithMessage("Expected identifier name as catch target"); … … 1492 1499 return 0; 1493 1500 case IDENT: 1501 case YIELD: 1494 1502 result = parseExpressionOrLabelStatement(context); 1495 1503 break; … … 1581 1589 case SourceParseMode::MethodMode: 1582 1590 return "method"; 1591 case SourceParseMode::GeneratorMode: 1592 return "generator"; 1583 1593 case SourceParseMode::ArrowFunctionMode: 1584 1594 return "arrow function"; … … 1600 1610 functionInfo.parameters = parameterList; 1601 1611 functionInfo.startOffset = parametersStart; 1612 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Parameters); 1602 1613 1603 1614 if (mode == SourceParseMode::ArrowFunctionMode) { … … 1658 1669 1659 1670 template <typename LexerType> 1660 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, SourceParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, Function ParseType parseType)1671 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, SourceParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, FunctionDefinitionType functionDefinitionType) 1661 1672 { 1662 1673 RELEASE_ASSERT(isFunctionParseMode(mode)); 1663 1674 1675 bool upperScopeIsGenerator = currentScope()->isGenerator(); 1664 1676 AutoPopScopeRef functionScope(this, pushScope()); 1665 functionScope->setIsFunction(); 1677 functionScope->setSourceParseMode(mode); 1678 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Body); 1666 1679 int functionNameStart = m_token.m_location.startOffset; 1667 1680 const Identifier* lastFunctionName = m_lastFunctionName; … … 1671 1684 int startColumn; 1672 1685 FunctionBodyType functionBodyType; 1673 1674 switch (parseType) { 1675 case StandardFunctionParseType: { 1676 RELEASE_ASSERT(mode != SourceParseMode::ArrowFunctionMode); 1677 if (match(IDENT) || isLETMaskedAsIDENT()) { 1686 1687 if (mode == SourceParseMode::ArrowFunctionMode) { 1688 startLocation = tokenLocation(); 1689 functionInfo.startLine = tokenLine(); 1690 startColumn = tokenColumn(); 1691 1692 parametersStart = parseFunctionParameters(context, mode, functionInfo); 1693 propagateError(); 1694 1695 matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration"); 1696 1697 if (m_lexer->prevTerminator()) 1698 failDueToUnexpectedToken(); 1699 1700 ASSERT(constructorKind == ConstructorKind::None); 1701 1702 // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function 1703 // and we need use common approach to parse function body 1704 next(); 1705 functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression; 1706 } else { 1707 // http://ecma-international.org/ecma-262/6.0/#sec-function-definitions 1708 // FunctionExpression : 1709 // function BindingIdentifieropt ( FormalParameters ) { FunctionBody } 1710 // 1711 // FunctionDeclaration[Yield, Default] : 1712 // function BindingIdentifier[?Yield] ( FormalParameters ) { FunctionBody } 1713 // [+Default] function ( FormalParameters ) { FunctionBody } 1714 // 1715 // GeneratorDeclaration[Yield, Default] : 1716 // function * BindingIdentifier[?Yield] ( FormalParameters[Yield] ) { GeneratorBody } 1717 // [+Default] function * ( FormalParameters[Yield] ) { GeneratorBody } 1718 // 1719 // GeneratorExpression : 1720 // function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody } 1721 // 1722 // The name of FunctionExpression can accept "yield" even in the context of generator. 1723 if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode) 1724 upperScopeIsGenerator = false; 1725 1726 if (matchSpecIdentifier(upperScopeIsGenerator)) { 1678 1727 functionInfo.name = m_token.m_data.ident; 1679 1728 m_lastFunctionName = functionInfo.name; … … 1707 1756 1708 1757 functionBodyType = StandardFunctionBodyBlock; 1709 1710 break; 1711 } 1712 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 1713 case ArrowFunctionParseType: { 1714 RELEASE_ASSERT(mode == SourceParseMode::ArrowFunctionMode); 1715 1716 startLocation = tokenLocation(); 1717 functionInfo.startLine = tokenLine(); 1718 startColumn = tokenColumn(); 1719 1720 parametersStart = parseFunctionParameters(context, mode, functionInfo); 1721 propagateError(); 1722 1723 matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration"); 1724 1725 if (m_lexer->prevTerminator()) 1726 failDueToUnexpectedToken(); 1727 1728 ASSERT(constructorKind == ConstructorKind::None); 1729 1730 // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function 1731 // and we need use common approach to parse function body 1732 next(); 1733 functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression; 1734 1735 break; 1736 } 1737 #else 1738 default: 1739 RELEASE_ASSERT_NOT_REACHED(); 1740 #endif 1741 } 1742 1758 } 1759 1743 1760 bool isClassConstructor = constructorKind != ConstructorKind::None; 1744 1761 … … 1762 1779 unsigned currentLineStartOffset = m_token.m_location.lineStartOffset; 1763 1780 1764 bool isArrowFunction = parseType == ArrowFunctionParseType;1781 bool isArrowFunction = mode == SourceParseMode::ArrowFunctionMode; 1765 1782 1766 1783 functionInfo.body = context.createFunctionMetadata( … … 1810 1827 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 1811 1828 if (functionScope->strictMode() && functionInfo.name) { 1812 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode );1829 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorMode); 1813 1830 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 1814 1831 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); … … 1875 1892 next(); 1876 1893 ParserFunctionInfo<TreeBuilder> functionInfo; 1877 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, SourceParseMode::NormalFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, 1878 functionKeywordStart, functionInfo, StandardFunctionParseType)), "Cannot parse this function"); 1894 SourceParseMode parseMode = SourceParseMode::NormalFunctionMode; 1895 #if ENABLE(ES6_GENERATORS) 1896 if (consume(TIMES)) 1897 parseMode = SourceParseMode::GeneratorMode; 1898 #endif 1899 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this function"); 1879 1900 failIfFalse(functionInfo.name, "Function statements must have a name"); 1901 1880 1902 DeclarationResultMask declarationResult = declareVariable(functionInfo.name); 1881 1903 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode"); … … 1977 1999 bool isGetter = false; 1978 2000 bool isSetter = false; 2001 bool isGenerator = false; 2002 #if ENABLE(ES6_GENERATORS) 2003 if (consume(TIMES)) 2004 isGenerator = true; 2005 #endif 1979 2006 switch (m_token.m_type) { 1980 2007 case STRING: … … 1987 2014 ASSERT(ident); 1988 2015 next(); 1989 if ( match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET)) {2016 if (!isGenerator && (match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) { 1990 2017 isGetter = *ident == propertyNames.get; 1991 2018 isSetter = *ident == propertyNames.set; … … 2017 2044 ParserFunctionInfo<TreeBuilder> methodInfo; 2018 2045 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 2019 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 2046 SourceParseMode parseMode = SourceParseMode::MethodMode; 2047 if (isGenerator) { 2048 isConstructor = false; 2049 parseMode = SourceParseMode::GeneratorMode; 2050 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'"); 2051 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'"); 2052 } 2053 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 2020 2054 methodInfo.name = isConstructor ? className : ident; 2021 2055 … … 2104 2138 labels.append(LabelInfo(ident, start, end)); 2105 2139 } 2106 } while (match (IDENT) || isLETMaskedAsIDENT());2140 } while (matchSpecIdentifier()); 2107 2141 bool isLoop = false; 2108 2142 switch (m_token.m_type) { … … 2467 2501 const Identifier* localName = nullptr; 2468 2502 SavePoint savePoint = createSavePoint(); 2469 if (match(FUNCTION) 2503 2504 bool startsWithFunction = match(FUNCTION); 2505 if (startsWithFunction 2470 2506 #if ENABLE(ES6_CLASS_SYNTAX) 2471 2507 || match(CLASSTOKEN) … … 2474 2510 isFunctionOrClassDeclaration = true; 2475 2511 next(); 2476 // FIXME: When landing ES6 generators, we need to take care of that '*' comes. 2512 2513 #if ENABLE(ES6_GENERATORS) 2514 // ES6 Generators 2515 if (startsWithFunction && match(TIMES)) 2516 next(); 2517 #endif 2477 2518 if (match(IDENT)) 2478 2519 localName = m_token.m_data.ident; … … 2663 2704 restoreSavePoint(savePoint); 2664 2705 } 2665 2706 2707 #if ENABLE(ES6_GENERATORS) 2708 if (match(YIELD)) 2709 return parseYieldExpression(context); 2710 #endif 2711 2666 2712 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) 2667 2713 if (isArrowFunctionParamters()) … … 2729 2775 2730 2776 return lhs; 2777 } 2778 2779 template <typename LexerType> 2780 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseYieldExpression(TreeBuilder& context) 2781 { 2782 // YieldExpression[In] : 2783 // yield 2784 // yield [no LineTerminator here] AssignmentExpression[?In, Yield] 2785 // yield [no LineTerminator here] * AssignmentExpression[?In, Yield] 2786 2787 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions 2788 failIfFalse(currentScope()->isGenerator(), "Cannot use yield expression out of generator"); 2789 2790 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors 2791 failIfTrue(m_functionParsePhase == FunctionParsePhase::Parameters, "Cannot use yield expression within parameters"); 2792 2793 JSTokenLocation location(tokenLocation()); 2794 ASSERT(match(YIELD)); 2795 SavePoint savePoint = createSavePoint(); 2796 next(); 2797 if (m_lexer->prevTerminator()) 2798 return context.createYield(location); 2799 2800 bool delegate = consume(TIMES); 2801 TreeExpression argument = parseAssignmentExpression(context); 2802 if (!argument) { 2803 restoreSavePoint(savePoint); 2804 next(); 2805 return context.createYield(location); 2806 } 2807 return context.createYield(location, argument, delegate); 2731 2808 } 2732 2809 … … 2815 2892 { 2816 2893 bool wasIdent = false; 2894 bool isGenerator = false; 2895 #if ENABLE(ES6_GENERATORS) 2896 if (consume(TIMES)) 2897 isGenerator = true; 2898 #endif 2817 2899 switch (m_token.m_type) { 2818 2900 namedProperty: … … 2823 2905 const Identifier* ident = m_token.m_data.ident; 2824 2906 unsigned getterOrSetterStartOffset = tokenStart(); 2825 if (complete || (wasIdent && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))2907 if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set))) 2826 2908 nextExpectIdentifier(LexerFlagsIgnoreReservedWords); 2827 2909 else 2828 2910 nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); 2829 2911 2830 if ( match(COLON)) {2912 if (!isGenerator && match(COLON)) { 2831 2913 next(); 2832 2914 TreeExpression node = parseAssignmentExpression(context); … … 2837 2919 2838 2920 if (match(OPENPAREN)) { 2839 auto method = parsePropertyMethod(context, ident );2921 auto method = parsePropertyMethod(context, ident, isGenerator); 2840 2922 propagateError(); 2841 2923 return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete); 2842 2924 } 2925 failIfTrue(isGenerator, "Expected a parenthesis for argument list"); 2843 2926 2844 2927 failIfFalse(wasIdent, "Expected an identifier as property name"); … … 2868 2951 if (match(OPENPAREN)) { 2869 2952 const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName); 2870 auto method = parsePropertyMethod(context, &ident );2953 auto method = parsePropertyMethod(context, &ident, isGenerator); 2871 2954 propagateError(); 2872 2955 return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete); 2873 2956 } 2957 failIfTrue(isGenerator, "Expected a parenthesis for argument list"); 2874 2958 2875 2959 consumeOrFail(COLON, "Expected ':' after property name"); … … 2886 2970 2887 2971 if (match(OPENPAREN)) { 2888 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier );2972 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator); 2889 2973 propagateError(); 2890 2974 return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete); 2891 2975 } 2976 failIfTrue(isGenerator, "Expected a parenthesis for argument list"); 2892 2977 2893 2978 consumeOrFail(COLON, "Expected ':' after property name"); … … 2904 2989 2905 2990 template <typename LexerType> 2906 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName )2991 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator) 2907 2992 { 2908 2993 JSTokenLocation methodLocation(tokenLocation()); 2909 2994 unsigned methodStart = tokenStart(); 2910 2995 ParserFunctionInfo<TreeBuilder> methodInfo; 2911 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::MethodMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 2996 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorMode : SourceParseMode::MethodMode; 2997 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 2912 2998 methodInfo.name = methodName; 2913 2999 return context.createFunctionExpr(methodLocation, methodInfo); … … 2924 3010 JSTokenLocation location(tokenLocation()); 2925 3011 2926 if (match (IDENT) || match(STRING) || isLETMaskedAsIDENT()) {3012 if (matchSpecIdentifier() || match(STRING)) { 2927 3013 stringPropertyName = m_token.m_data.ident; 2928 3014 semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->prototype, … … 2945 3031 if (type & PropertyNode::Getter) { 2946 3032 failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition"); 2947 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::GetterMode, false, constructorKind, superBinding, 2948 getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse getter definition"); 3033 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::GetterMode, false, constructorKind, superBinding, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse getter definition"); 2949 3034 } else { 2950 3035 failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition"); 2951 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::SetterMode, false, constructorKind, superBinding, 2952 getterOrSetterStartOffset, info, StandardFunctionParseType)), "Cannot parse setter definition"); 3036 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::SetterMode, false, constructorKind, superBinding, getterOrSetterStartOffset, info, FunctionDefinitionType::Method)), "Cannot parse setter definition"); 2953 3037 } 2954 3038 … … 3151 3235 } 3152 3236 3237 template <typename LexerType> 3238 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseFunctionExpression(TreeBuilder& context) 3239 { 3240 ASSERT(match(FUNCTION)); 3241 JSTokenLocation location(tokenLocation()); 3242 unsigned functionKeywordStart = tokenStart(); 3243 next(); 3244 ParserFunctionInfo<TreeBuilder> functionInfo; 3245 functionInfo.name = &m_vm->propertyNames->nullIdentifier; 3246 SourceParseMode parseMode = SourceParseMode::NormalFunctionMode; 3247 #if ENABLE(ES6_GENERATORS) 3248 if (consume(TIMES)) 3249 parseMode = SourceParseMode::GeneratorMode; 3250 #endif 3251 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression)), "Cannot parse function expression"); 3252 return context.createFunctionExpr(location, functionInfo); 3253 } 3254 3153 3255 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX) 3154 3256 template <typename LexerType> … … 3216 3318 failIfStackOverflow(); 3217 3319 switch (m_token.m_type) { 3218 case FUNCTION: { 3219 JSTokenLocation location(tokenLocation()); 3220 unsigned functionKeywordStart = tokenStart(); 3221 next(); 3222 ParserFunctionInfo<TreeBuilder> info; 3223 info.name = &m_vm->propertyNames->nullIdentifier; 3224 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::NormalFunctionMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, StandardFunctionParseType)), "Cannot parse function expression"); 3225 return context.createFunctionExpr(location, info); 3226 } 3320 case FUNCTION: 3321 return parseFunctionExpression(context); 3227 3322 #if ENABLE(ES6_CLASS_SYNTAX) 3228 3323 case CLASSTOKEN: { … … 3317 3412 return parseTemplateLiteral(context, LexerType::RawStringsBuildMode::DontBuildRawStrings); 3318 3413 #endif 3414 case YIELD: 3415 if (!strictMode() && !currentScope()->isGenerator()) 3416 goto identifierExpression; 3417 failDueToUnexpectedToken(); 3319 3418 case LET: 3320 3419 if (!strictMode()) … … 3494 3593 ParserFunctionInfo<TreeBuilder> info; 3495 3594 info.name = &m_vm->propertyNames->nullIdentifier; 3496 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, ArrowFunctionParseType)), "Cannot parse arrow function expression");3595 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); 3497 3596 3498 3597 return context.createArrowFunctionExpr(location, info);
Note:
See TracChangeset
for help on using the changeset viewer.