Ejemplo n.º 1
0
/*
  GRAMMAR OF A VARIABLE DECLARATION
 
 ‌ variable-declaration → variable-declaration-head pattern-initializer-list
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation code-block
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-block
  variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block
 ‌ variable-declaration → variable-declaration-head variable-name type-annotation initializer opt willSet-didSet-block
 ‌ variable-declaration-head → attributes opt declaration-specifiers opt var
 ‌ variable-name → identifier
*/
DeclarationPtr Parser::parseVar(const std::vector<AttributePtr>& attrs, int specifiers)
{

    Token token;
    expect(Keyword::Var, token);
    Flags flags(this, UNDER_VAR);
    //try read it as pattern-initializer-list
    ValueBindingsPtr ret = nodeFactory->createValueBindings(token.state);
    ret->setReadOnly(false);
    ret->setAttributes(attrs);
    ret->setSpecifiers(specifiers);
    ValueBindingPtr var = parseVariableDeclaration();
    var->setSpecifiers(specifiers);
    ret->add(var);
    if(predicate(L","))
    {
        while(match(L","))
        {
            var = parseVariableDeclaration();
            var->setSpecifiers(specifiers);
            ret->add(var);
        }
        return ret;
    }

    if(!match(L"{"))
        return ret;
    peek(token);
    IdentifierPtr name = std::dynamic_pointer_cast<Identifier>(var->getName());
    tassert(token, name != nullptr, Errors::E_GETTER_SETTER_CAN_ONLY_BE_DEFINED_FOR_A_SINGLE_VARIABLE, L"");


    ComputedPropertyPtr prop = nodeFactory->createComputedProperty(*var->getSourceInfo());
    prop->setAttributes(attrs);
    prop->setSpecifiers(specifiers);
    prop->setTypeAttributes(var->getTypeAttributes());
    prop->setName(name->getIdentifier());
    prop->setDeclaredType(var->getDeclaredType());
    prop->setInitializer(var->getInitializer());
    var = nullptr;
    ret = nullptr;

    if(token.type != TokenType::CloseBrace)
    {
        Flags flags(this, SUPPRESS_TRAILING_CLOSURE);
        switch(token.getKeyword())
        {
            case Keyword::Get:
            case Keyword::Set:
                if(this->flags & UNDER_PROTOCOL)
                {
                    // variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-keyword-block
                    //no code block for getter/setter for protocol
                    std::pair<CodeBlockPtr, CodeBlockPtr> r = parseGetterSetterKeywordBlock();
                    prop->setGetter(r.first);
                    prop->setSetter(r.second);
                }
                else
                {
                    //  variable-declaration → variable-declaration-head variable-name type-annotation getter-setter-block
                    std::pair<CodeBlockPtr, std::pair<std::wstring, CodeBlockPtr> > r = parseGetterSetterBlock();
                    prop->setGetter(r.first);
                    prop->setSetterName(r.second.first);
                    prop->setSetter(r.second.second);
                }
                break;
            case Keyword::WillSet:
            case Keyword::DidSet:
                //  variable-declaration → variable-declaration-head variable-name type-annotation initializer opt willSet-didSet-block
                parseWillSetDidSetBlock(prop);
                break;
            default:
                //‌ variable-declaration → variable-declaration-head variable-name type-annotation code-block
                CodeBlockPtr getter = nodeFactory->createCodeBlock(token.state);
                prop->setGetter(getter);
                do
                {
                    StatementPtr st = parseStatement();
                    getter->addStatement(st);
                }while(!predicate(L"}"));
                break;
        }
        
    }
    expect(L"}");
    return prop;
}