Example #1
0
void FunctionAnalyzer::visitComputedProperty(const ComputedPropertyPtr& node)
{
    CodeBlockPtr didSet = node->getDidSet();
    CodeBlockPtr willSet = node->getWillSet();
    CodeBlockPtr getter = node->getGetter();
    CodeBlockPtr setter = node->getSetter();
    TypePtr type = declarationAnalyzer->resolveType(node->getDeclaredType(), true);
    assert(type != nullptr);

    shared_ptr<ComposedComputedProperty> property = static_pointer_cast<ComposedComputedProperty>(node);
    //prepare type for getter/setter
    /*
    std::vector<Parameter> params;
    TypePtr getterType = Type::newFunction(params, type, nullptr);
    params.push_back(Parameter(type));
    TypePtr setterType = Type::newFunction(params, symbolRegistry->getGlobalScope()->Void(), false);

    */
    SCOPED_SET(ctx->flags, (ctx->flags & (~SemanticContext::FLAG_PROCESS_DECLARATION)) | SemanticContext::FLAG_PROCESS_IMPLEMENTATION);
    if(!property->hasModifier(DeclarationModifiers::_Generated))
    {
        if(property->functions.getter)
            property->functions.getter->accept(semanticAnalyzer);
        if(property->functions.setter)
            property->functions.setter->accept(semanticAnalyzer);
        if(property->functions.willSet)
            property->functions.willSet->accept(semanticAnalyzer);
        if(property->functions.didSet)
            property->functions.didSet->accept(semanticAnalyzer);
    }
}
Example #2
0
TEST(TestProtocol, testOptional)
{
    PARSE_STATEMENT(L"@objc protocol CounterDataSource {\n"
                    L"optional func incrementForCount(count: Int) -> Int\n"
                    L"optional var fixedIncrement: Int { get }\n"
                    L"}");
    ProtocolDefPtr p;
    ASSERT_NOT_NULL(p = std::dynamic_pointer_cast<ProtocolDef>(root));
    ASSERT_EQ(2, p->numDeclarations());
    ASSERT_NOT_NULL(p->getAttribute(L"objc"));



    FunctionDefPtr f;

    ASSERT_NOT_NULL(f = std::dynamic_pointer_cast<FunctionDef>(p->getDeclaration(0)));
    ASSERT_EQ(L"incrementForCount", f->getName());
    ASSERT_TRUE(f->getModifiers() & DeclarationModifiers::Optional);

    ComputedPropertyPtr var;

    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ComputedProperty>(p->getDeclaration(1)));
    ASSERT_TRUE(f->getModifiers() & DeclarationModifiers::Optional);
    ASSERT_EQ(L"fixedIncrement", var->getName());
    ASSERT_NOT_NULL(var->getGetter());
    ASSERT_NULL(var->getSetter());

}
Example #3
0
void NodeVisitor::visitComputedProperty(const ComputedPropertyPtr& node)
{
    ACCEPT(node->getInitializer());
    ACCEPT(node->getGetter());
    ACCEPT(node->getSetter());
    ACCEPT(node->getWillSet());
    ACCEPT(node->getDidSet());
}
Example #4
0
TEST(TestProtocol, testPropertyRequirements)
{
    PARSE_STATEMENT(L"protocol SomeProtocol {\n"
                    L"var mustBeSettable: Int { get set }\n"
                    L"var doesNotNeedToBeSettable: Int { get }\n"
                    L"}");
    ProtocolDefPtr p;
    ASSERT_NOT_NULL(p = std::dynamic_pointer_cast<ProtocolDef>(root));
    ASSERT_EQ(2, p->numDeclarations());
    ComputedPropertyPtr var;

    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ComputedProperty>(p->getDeclaration(0)));
    ASSERT_EQ(L"mustBeSettable", var->getName());
    ASSERT_EQ(0, var->getModifiers());
    ASSERT_NOT_NULL(var->getGetter());
    ASSERT_NOT_NULL(var->getSetter());



    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ComputedProperty>(p->getDeclaration(1)));
    ASSERT_EQ(L"doesNotNeedToBeSettable", var->getName());
    ASSERT_NOT_NULL(var->getGetter());
    ASSERT_NULL(var->getSetter());

}
Example #5
0
TEST(TestProtocol, testPropertyRequirements2)
{
    PARSE_STATEMENT(L"protocol AnotherProtocol {\n"
                    L"class var someTypeProperty: Int { get set }\n"
                    L"}");
    ProtocolDefPtr p;
    ASSERT_NOT_NULL(p = std::dynamic_pointer_cast<ProtocolDef>(root));
    ASSERT_EQ(1, p->numDeclarations());
    ComputedPropertyPtr var;

    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ComputedProperty>(p->getDeclaration(0)));
    ASSERT_EQ((int)DeclarationModifiers::Class, var->getModifiers());
    ASSERT_EQ(L"someTypeProperty", var->getName());
    ASSERT_NOT_NULL(var->getGetter());
    ASSERT_NOT_NULL(var->getSetter());

}
Example #6
0
TEST(TestProtocol, testPropertyRequirements3)
{
    PARSE_STATEMENT(L"protocol FullyNamed {\n"
                    L"var fullName: String { get }\n"
                    L"}");
    ProtocolDefPtr p;
    ASSERT_NOT_NULL(p = std::dynamic_pointer_cast<ProtocolDef>(root));
    ASSERT_EQ(1, p->numDeclarations());
    ComputedPropertyPtr var;

    ASSERT_NOT_NULL(var = std::dynamic_pointer_cast<ComputedProperty>(p->getDeclaration(0)));
    ASSERT_EQ(0, var->getModifiers());
    ASSERT_EQ(L"fullName", var->getName());
    ASSERT_NOT_NULL(var->getGetter());
    ASSERT_NULL(var->getSetter());

}
/*
 ‌ didSet-clause → attributes opt didSet setter-name opt code-block
*/
void Parser::parseDidSetClause(const ComputedPropertyPtr& property, bool opt)
{
    Token token;
    if(!peek(token))
        return;
    if(opt && token.type == TokenType::CloseBrace)
        return;
    Attributes attrs;
    parseAttributes(attrs);
    expect(Keyword::DidSet);
    if(match(L"("))
    {
        expect_identifier(token);
        property->setDidSetSetter(token.token);
        expect(L")");
    }
    CodeBlockPtr cb = parseCodeBlock();
    property->setDidSet(cb);
}
/*
  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;
}