Changeset 187012 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jul 19, 2015, 9:57:44 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r186959 r187012 415 415 switch (m_token.m_type) { 416 416 case CONSTTOKEN: 417 result = parse ConstDeclaration(context);417 result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration); 418 418 break; 419 419 case LET: { … … 427 427 } 428 428 if (shouldParseVariableDeclaration) 429 result = parseVariableDeclaration(context, DeclarationType::Le xicalDeclaration);429 result = parseVariableDeclaration(context, DeclarationType::LetDeclaration); 430 430 else 431 431 result = parseExpressionOrLabelStatement(context); // Treat this as an IDENT. This is how ::parseStatement() handles IDENT. … … 454 454 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVariableDeclaration(TreeBuilder& context, DeclarationType declarationType) 455 455 { 456 ASSERT(match(VAR) || match(LET) );456 ASSERT(match(VAR) || match(LET) || match(CONSTTOKEN)); 457 457 JSTokenLocation location(tokenLocation()); 458 458 int start = tokenLine(); … … 462 462 TreeExpression scratch2 = 0; 463 463 JSTextPosition scratch3; 464 TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType); 464 bool scratchBool; 465 TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType, scratchBool); 465 466 propagateError(); 466 failIfFalse(autoSemiColon(), "Expected ';' after var declaration"); 467 468 if (declarationType == DeclarationType::VarDeclaration) 469 return context.createVarStatement(location, variableDecls, start, end); 470 ASSERT(declarationType == DeclarationType::LexicalDeclaration); 471 return context.createLetStatement(location, variableDecls, start, end); 472 } 473 474 template <typename LexerType> 475 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseConstDeclaration(TreeBuilder& context) 476 { 477 ASSERT(match(CONSTTOKEN)); 478 JSTokenLocation location(tokenLocation()); 479 int start = tokenLine(); 480 int end = 0; 481 TreeConstDeclList constDecls = parseConstDeclarationList(context); 482 propagateError(); 483 failIfFalse(autoSemiColon(), "Expected ';' after const declaration"); 484 485 return context.createConstStatement(location, constDecls, start, end); 467 failIfFalse(autoSemiColon(), "Expected ';' after variable declaration"); 468 469 return context.createDeclarationStatement(location, variableDecls, start, end); 486 470 } 487 471 … … 534 518 535 519 template <typename LexerType> 536 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType )537 { 538 ASSERT(declarationType == DeclarationType::Le xicalDeclaration || declarationType == DeclarationType::VarDeclaration);520 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType, bool& forLoopConstDoesNotHaveInitializer) 521 { 522 ASSERT(declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::VarDeclaration || declarationType == DeclarationType::ConstDeclaration); 539 523 TreeExpression head = 0; 540 524 TreeExpression tail = 0; 541 525 const Identifier* lastIdent; 542 526 JSToken lastIdentToken; 527 AssignmentContext assignmentContext = assignmentContextFromDeclarationType(declarationType); 543 528 do { 544 529 lastIdent = 0; … … 550 535 bool hasInitializer = false; 551 536 if (match(IDENT) || isLETMaskedAsIDENT()) { 552 failIfTrue(isLETMaskedAsIDENT() && declarationType == DeclarationType::LexicalDeclaration, "Can't use 'let' as an identifier name for a LexicalDeclaration"); 537 failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 538 "Can't use 'let' as an identifier name for a LexicalDeclaration"); 553 539 JSTextPosition varStart = tokenStartPosition(); 554 540 JSTokenLocation varStartLocation(tokenLocation()); … … 559 545 next(); 560 546 hasInitializer = match(EQUAL); 561 if (!declareVariable(name, declarationType)) { 562 if (declarationType == DeclarationType::LexicalDeclaration) 563 internalFailWithMessage(false, "Cannot declare a lexical variable twice: '", name->impl(), "'"); 564 else if (strictMode()) 565 internalFailWithMessage(false, "Cannot declare a variable named ", name->impl(), " in strict mode"); 547 DeclarationResultMask declarationResult = declareVariable(name, declarationType); 548 if (declarationResult != DeclarationResult::Valid) { 549 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named ", name->impl(), " in strict mode"); 550 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) { 551 if (declarationType == DeclarationType::LetDeclaration) 552 internalFailWithMessage(false, "Cannot declare a let variable twice: '", name->impl(), "'"); 553 if (declarationType == DeclarationType::ConstDeclaration) 554 internalFailWithMessage(false, "Cannot declare a const variable twice: '", name->impl(), "'"); 555 RELEASE_ASSERT_NOT_REACHED(); 556 } 566 557 } 567 558 if (hasInitializer) { … … 574 565 failIfFalse(initializer, "Expected expression as the intializer for the variable '", name->impl(), "'"); 575 566 576 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition(), AssignmentContext::DeclarationStatement);567 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition(), assignmentContext); 577 568 } else { 569 if (declarationListContext == ForLoopContext && declarationType == DeclarationType::ConstDeclaration) 570 forLoopConstDoesNotHaveInitializer = true; 571 failIfTrue(declarationListContext != ForLoopContext && declarationType == DeclarationType::ConstDeclaration, "const declared variable '", name->impl(), "'", " must have an initializer"); 578 572 if (declarationType == DeclarationType::VarDeclaration) 579 573 node = context.createEmptyVarExpression(varStartLocation, *name); … … 583 577 } else { 584 578 lastIdent = 0; 585 auto pattern = parseDestructuringPattern(context, de clarationType == DeclarationType::VarDeclaration ? DestructureToVariables : DestructureToLexicalVariables, AssignmentContext::DeclarationStatement);579 auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), assignmentContext); 586 580 failIfFalse(pattern, "Cannot parse this destructuring pattern"); 587 581 hasInitializer = match(EQUAL); … … 605 599 } while (match(COMMA)); 606 600 if (lastIdent) 607 lastPattern = context.createBindingLocation(lastIdentToken.m_location, *lastIdent, lastIdentToken.m_startPosition, lastIdentToken.m_endPosition, AssignmentContext::DeclarationStatement);601 lastPattern = context.createBindingLocation(lastIdentToken.m_location, *lastIdent, lastIdentToken.m_startPosition, lastIdentToken.m_endPosition, assignmentContext); 608 602 609 603 return head; … … 618 612 if (depth) { 619 613 if (kind == DestructureToVariables) 620 failIfFalseIfStrict(declareVariable(&name), "Cannot deconstruct to a variable named '", name.impl(), "' in strict mode"); 621 else if (kind == DestructureToLexicalVariables) 622 semanticFailIfFalse(declareVariable(&name, DeclarationType::LexicalDeclaration), "Cannot declare a lexical variable twice: '", name.impl(), "'"); 623 else if (kind == DestructureToParameters) { 614 failIfTrueIfStrict(declareVariable(&name) & DeclarationResult::InvalidStrictMode, "Cannot deconstruct to a variable named '", name.impl(), "' in strict mode"); 615 else if (kind == DestructureToLet || kind == DestructureToConst) { 616 DeclarationResultMask declarationResult = declareVariable(&name, kind == DestructureToLet ? DeclarationType::LetDeclaration : DeclarationType::ConstDeclaration); 617 if (declarationResult != DeclarationResult::Valid) { 618 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot destructure to a variable named '", name.impl(), "' in strict mode"); 619 failIfTrue(declarationResult & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare a lexical variable twice: '", name.impl(), "'"); 620 } 621 } else if (kind == DestructureToParameters) { 624 622 auto bindingResult = declareBoundParameter(&name); 625 623 if (bindingResult == Scope::StrictBindingFailed && strictMode()) { 626 semanticFailIfTrue( m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot destructure to a parameter name '", name.impl(), "' in strict mode");624 semanticFailIfTrue(isEvalOrArguments(&name), "Cannot destructure to a parameter name '", name.impl(), "' in strict mode"); 627 625 if (m_lastFunctionName && name == *m_lastFunctionName) 628 626 semanticFail("Cannot destructure to '", name.impl(), "' as it shadows the name of a strict mode function"); … … 642 640 } else { 643 641 if (kind == DestructureToVariables) 644 failIfFalseIfStrict(declareVariable(&name), "Cannot declare a variable named '", name.impl(), "' in strict mode"); 645 else if (kind == DestructureToLexicalVariables) 646 semanticFailIfFalse(declareVariable(&name, DeclarationType::LexicalDeclaration), "Cannot declare a lexical variable twice: '", name.impl(), "'"); 647 else if (kind == DestructureToParameters) { 648 bool declarationResult = declareParameter(&name); 649 if (!declarationResult && strictMode()) { 650 semanticFailIfTrue(m_vm->propertyNames->arguments == name || m_vm->propertyNames->eval == name, "Cannot destructure to a parameter name '", name.impl(), "' in strict mode"); 642 failIfTrueIfStrict(declareVariable(&name) & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named '", name.impl(), "' in strict mode"); 643 else if (kind == DestructureToLet || kind == DestructureToConst) { 644 DeclarationResultMask declarationResult = declareVariable(&name, kind == DestructureToLet ? DeclarationType::LetDeclaration : DeclarationType::ConstDeclaration); 645 if (declarationResult != DeclarationResult::Valid) { 646 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot destructure to a variable named '", name.impl(), "' in strict mode"); 647 failIfTrue(declarationResult & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare a lexical variable twice: '", name.impl(), "'"); 648 } 649 } else if (kind == DestructureToParameters) { 650 DeclarationResultMask declarationResult = declareParameter(&name); 651 if ((declarationResult & DeclarationResult::InvalidStrictMode) && strictMode()) { 652 semanticFailIfTrue(isEvalOrArguments(&name), "Cannot destructure to a parameter name '", name.impl(), "' in strict mode"); 651 653 if (m_lastFunctionName && name == *m_lastFunctionName) 652 654 semanticFail("Cannot declare a parameter named '", name.impl(), "' as it shadows the name of a strict mode function"); … … 766 768 JSTokenLocation location = m_token.m_location; 767 769 if (match(IDENT) || isLETMaskedAsIDENT()) { 768 failIfTrue( isLETMaskedAsIDENT() && kind == DestructureToLexicalVariables, "Can't use 'let' as an identifier name for a LexicalDeclaration");770 failIfTrue(match(LET) && (kind == DestructureToLet || kind == DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 769 771 propertyName = *m_token.m_data.ident; 770 772 JSToken identifierToken = m_token; … … 828 830 failWithMessage("Expected a parameter pattern or a ')' in parameter list"); 829 831 } 830 failIfTrue( isLETMaskedAsIDENT() && kind == DestructureToLexicalVariables, "Can't use 'let' as an identifier name for a LexicalDeclaration");832 failIfTrue(match(LET) && (kind == DestructureToLet || kind == DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 831 833 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token, bindingContext); 832 834 next(); … … 846 848 next(TreeBuilder::DontBuildStrings); // consume '=' 847 849 return parseAssignmentExpression(context); 848 }849 850 template <typename LexerType>851 template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDeclarationList(TreeBuilder& context)852 {853 failIfTrue(strictMode(), "Const declarations are not supported in strict mode");854 TreeConstDeclList constDecls = 0;855 TreeConstDeclList tail = 0;856 do {857 JSTokenLocation location(tokenLocation());858 next();859 failIfFalse(match(IDENT), "Expected an identifier name in const declaration");860 const Identifier* name = m_token.m_data.ident;861 next();862 bool hasInitializer = match(EQUAL);863 // FIXME: This should be LexicalVariable when we support proper ES6 const semantics.864 declareVariable(name, DeclarationType::VarDeclaration, true);865 TreeExpression initializer = 0;866 if (hasInitializer) {867 next(TreeBuilder::DontBuildStrings); // consume '='868 initializer = parseAssignmentExpression(context);869 failIfFalse(!!initializer, "Unable to parse initializer");870 }871 tail = context.appendConstDecl(location, tail, name, initializer);872 if (!constDecls)873 constDecls = tail;874 } while (match(COMMA));875 return constDecls;876 850 } 877 851 … … 892 866 bool isVarDeclaraton = match(VAR); 893 867 bool isLetDeclaration = match(LET); 868 bool isConstDeclaration = match(CONSTTOKEN); 869 bool forLoopConstDoesNotHaveInitializer = false; 894 870 895 871 VariableEnvironment dummySet; … … 898 874 899 875 auto gatherLexicalVariablesIfNecessary = [&] { 900 if (isLetDeclaration ) {876 if (isLetDeclaration || isConstDeclaration) { 901 877 ScopeRef scope = lexicalScope.scope(); 902 878 lexicalVariables = &scope->finalizeLexicalEnvironment(); … … 906 882 907 883 auto popLexicalScopeIfNecessary = [&] { 908 if (isLetDeclaration )884 if (isLetDeclaration || isConstDeclaration) 909 885 popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo); 910 886 }; 911 887 912 if (isVarDeclaraton || isLetDeclaration ) {888 if (isVarDeclaraton || isLetDeclaration || isConstDeclaration) { 913 889 /* 914 for (var/let IDENT inexpression) statement915 for (var/let varDeclarationList; expressionOpt; expressionOpt)890 for (var/let/const IDENT in/of expression) statement 891 for (var/let/const varDeclarationList; expressionOpt; expressionOpt) 916 892 */ 917 if (isLetDeclaration ) {893 if (isLetDeclaration || isConstDeclaration) { 918 894 ScopeRef newScope = pushScope(); 919 895 newScope->setIsLexicalScope(); … … 927 903 JSTextPosition initStart; 928 904 JSTextPosition initEnd; 929 decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, isVarDeclaraton ? DeclarationType::VarDeclaration : DeclarationType::LexicalDeclaration); 905 DeclarationType declarationType; 906 if (isVarDeclaraton) 907 declarationType = DeclarationType::VarDeclaration; 908 else if (isLetDeclaration) 909 declarationType = DeclarationType::LetDeclaration; 910 else if (isConstDeclaration) 911 declarationType = DeclarationType::ConstDeclaration; 912 else 913 RELEASE_ASSERT_NOT_REACHED(); 914 decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, declarationType, forLoopConstDoesNotHaveInitializer); 930 915 m_allowsIn = true; 931 916 propagateError(); … … 997 982 next(); 998 983 TreeExpression condition = 0; 984 failIfTrue(forLoopConstDoesNotHaveInitializer && isConstDeclaration, "const variables in for loops must have initializers"); 999 985 1000 986 if (!match(SEMICOLON)) { … … 1287 1273 next(); 1288 1274 AutoPopScopeRef catchScope(this, pushScope()); 1289 failIf FalseIfStrict(declareVariable(ident), "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");1275 failIfTrueIfStrict(declareVariable(ident) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode"); 1290 1276 catchScope->preventAllVariableDeclarations(); 1291 1277 handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target"); … … 1601 1587 next(); 1602 1588 if (!nameIsInContainingScope) 1603 failIf FalseIfStrict(functionScope->declareVariable(functionInfo.name), "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");1589 failIfTrueIfStrict(functionScope->declareVariable(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 1604 1590 } else if (requirements == FunctionNeedsName) { 1605 1591 if (match(OPENPAREN) && mode == NormalFunctionMode) … … 1797 1783 functionKeywordStart, functionInfo, StandardFunctionParseType)), "Cannot parse this function"); 1798 1784 failIfFalse(functionInfo.name, "Function statements must have a name"); 1799 failIf FalseIfStrict(declareVariable(functionInfo.name), "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");1785 failIfTrueIfStrict(declareVariable(functionInfo.name) & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode"); 1800 1786 return context.createFuncDeclStatement(location, functionInfo); 1801 1787 } … … 1837 1823 info.className = className; 1838 1824 next(); 1839 failIf False(classScope->declareVariable(className), "'", className->impl(), "' is not a valid class name");1825 failIfTrue(classScope->declareVariable(className) & DeclarationResult::InvalidStrictMode, "'", className->impl(), "' is not a valid class name"); 1840 1826 } else if (requirements == FunctionNeedsName) { 1841 1827 if (match(OPENBRACE)) … … 1913 1899 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 1914 1900 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, isStaticMethod ? NormalFunctionMode : MethodMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, StandardFunctionParseType)), "Cannot parse this method"); 1915 failIf False(ident && declareVariable(ident), "Cannot declare a method named '", methodInfo.name->impl(), "'");1901 failIfTrue(!ident || (declareVariable(ident) & DeclarationResult::InvalidStrictMode), "Cannot declare a method named '", methodInfo.name->impl(), "'"); 1916 1902 methodInfo.name = isConstructor ? className : ident; 1917 1903
Note:
See TracChangeset
for help on using the changeset viewer.