Changeset 187351 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jul 24, 2015, 11:40:58 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r187205 r187351 577 577 } else { 578 578 lastIdent = 0; 579 auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), assignmentContext);579 auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), nullptr, nullptr, assignmentContext); 580 580 failIfFalse(pattern, "Cannot parse this destructuring pattern"); 581 581 hasInitializer = match(EQUAL); … … 605 605 606 606 template <typename LexerType> 607 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token, AssignmentContext bindingContext )607 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token, AssignmentContext bindingContext, const Identifier** duplicateIdentifier) 608 608 { 609 609 ASSERT(!name.isNull()); 610 610 611 611 ASSERT(name.impl()->isAtomic() || name.impl()->isSymbol()); 612 if (depth) { 613 if (kind == DestructureToVariables) 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) { 612 613 if (kind == DestructureToVariables) 614 failIfTrueIfStrict(declareVariable(&name) & DeclarationResult::InvalidStrictMode, "Cannot declare 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) { 622 if (depth) { 622 623 auto bindingResult = declareBoundParameter(&name); 623 624 if (bindingResult == Scope::StrictBindingFailed && strictMode()) { … … 636 637 semanticFail("Cannot destructure to a parameter named '", name.impl(), "'"); 637 638 } 638 } 639 640 } else { 641 if (kind == DestructureToVariables) 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) { 639 } else { 650 640 DeclarationResultMask declarationResult = declareParameter(&name); 651 641 if ((declarationResult & DeclarationResult::InvalidStrictMode) && strictMode()) { … … 658 648 semanticFail("Cannot declare a parameter named '", name.impl(), "' in strict mode"); 659 649 } 650 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) { 651 // It's not always an error to define a duplicate parameter. 652 // It's only an error when there are default parameter values or destructuring parameters. 653 // We note this value now so we can check it later. 654 if (duplicateIdentifier) 655 *duplicateIdentifier = &name; 656 } 660 657 } 661 658 } … … 695 692 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context, AssignmentContext bindingContext) 696 693 { 697 return parseDestructuringPattern(context, DestructureToExpressions, bindingContext);698 } 699 700 template <typename LexerType> 701 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, AssignmentContext bindingContext, int depth)694 return parseDestructuringPattern(context, DestructureToExpressions, nullptr, nullptr, bindingContext); 695 } 696 697 template <typename LexerType> 698 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth) 702 699 { 703 700 failIfStackOverflow(); … … 710 707 next(); 711 708 709 if (hasDestructuringPattern) 710 *hasDestructuringPattern = true; 711 712 712 bool restElementWasFound = false; 713 713 … … 725 725 JSTokenLocation location = m_token.m_location; 726 726 next(); 727 auto innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1);727 auto innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 728 728 if (kind == DestructureToExpressions && !innerPattern) 729 729 return 0; … … 738 738 739 739 JSTokenLocation location = m_token.m_location; 740 auto innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1);740 auto innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 741 741 if (kind == DestructureToExpressions && !innerPattern) 742 742 return 0; 743 743 failIfFalse(innerPattern, "Cannot parse this destructuring pattern"); 744 744 TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context); 745 failIfTrue(kind == DestructureToParameters && defaultValue, "Default values in destructuring parameters are currently not supported");746 745 context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue); 747 746 } while (consume(COMMA)); … … 757 756 auto objectPattern = context.createObjectPattern(m_token.m_location); 758 757 next(); 758 759 if (hasDestructuringPattern) 760 *hasDestructuringPattern = true; 759 761 760 762 do { … … 773 775 next(); 774 776 if (consume(COLON)) 775 innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1);777 innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 776 778 else 777 innerPattern = createBindingPattern(context, kind, *propertyName, depth , identifierToken, bindingContext);779 innerPattern = createBindingPattern(context, kind, *propertyName, depth + 1, identifierToken, bindingContext, duplicateIdentifier); 778 780 } else { 779 781 JSTokenType tokenType = m_token.m_type; … … 806 808 failWithMessage("Expected a ':' prior to a named destructuring property"); 807 809 } 808 innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1);810 innerPattern = parseDestructuringPattern(context, kind, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1); 809 811 } 810 812 if (kind == DestructureToExpressions && !innerPattern) … … 812 814 failIfFalse(innerPattern, "Cannot parse this destructuring pattern"); 813 815 TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context); 814 failIfTrue(kind == DestructureToParameters && defaultValue, "Default values in destructuring parameters are currently not supported");815 816 ASSERT(propertyName); 816 817 context.appendObjectPatternEntry(objectPattern, location, wasString, *propertyName, innerPattern, defaultValue); … … 832 833 } 833 834 failIfTrue(match(LET) && (kind == DestructureToLet || kind == DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 834 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token, bindingContext );835 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token, bindingContext, duplicateIdentifier); 835 836 next(); 836 837 break; … … 1447 1448 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount) 1448 1449 { 1449 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1450 #define failFromDuplicate() \ 1451 if (duplicateParameter) {\ 1452 semanticFailIfTrue(defaultValue, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values");\ 1453 semanticFailIfTrue(hasDestructuringPattern, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with destructuring parameters");\ 1454 } 1455 1456 const Identifier* duplicateParameter = nullptr; 1457 bool hasDestructuringPattern = false; 1458 auto parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter, &hasDestructuringPattern); 1450 1459 failIfFalse(parameter, "Cannot parse parameter pattern"); 1451 context.appendParameter(list, parameter); 1460 auto defaultValue = parseDefaultValueForDestructuringPattern(context); 1461 propagateError(); 1462 failFromDuplicate(); 1463 context.appendParameter(list, parameter, defaultValue); 1452 1464 parameterCount++; 1453 1465 while (consume(COMMA)) { 1454 parameter = parseDestructuringPattern(context, DestructureToParameters );1466 parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter, &hasDestructuringPattern); 1455 1467 failIfFalse(parameter, "Cannot parse parameter pattern"); 1456 context.appendParameter(list, parameter); 1468 defaultValue = parseDefaultValueForDestructuringPattern(context); 1469 propagateError(); 1470 failFromDuplicate(); 1471 context.appendParameter(list, parameter, defaultValue); 1457 1472 parameterCount++; 1458 1473 } 1459 1474 return true; 1475 #undef failFromDuplicate 1460 1476 } 1461 1477 … … 1531 1547 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1532 1548 failIfFalse(parameter, "Cannot parse parameter pattern"); 1533 context.appendParameter(parameterList, parameter );1549 context.appendParameter(parameterList, parameter, 0); 1534 1550 } 1535 1551 } … … 1548 1564 } else if (mode == SetterMode) { 1549 1565 failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter"); 1550 auto parameter = parseDestructuringPattern(context, DestructureToParameters); 1566 const Identifier* duplicateParameter = nullptr; 1567 auto parameter = parseDestructuringPattern(context, DestructureToParameters, &duplicateParameter); 1551 1568 failIfFalse(parameter, "setter functions must have one parameter"); 1552 context.appendParameter(parameterList, parameter); 1569 auto defaultValue = parseDefaultValueForDestructuringPattern(context); 1570 propagateError(); 1571 semanticFailIfTrue(duplicateParameter && defaultValue, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values"); 1572 context.appendParameter(parameterList, parameter, defaultValue); 1553 1573 functionInfo.parameterCount = 1; 1554 1574 failIfTrue(match(COMMA), "setter functions must have one parameter");
Note:
See TracChangeset
for help on using the changeset viewer.