Ejemplo n.º 1
0
/*
  GRAMMAR OF AN INITIALIZER DECLARATION
 
 ‌ initializer-declaration → initializer-head generic-parameter-clause opt parameter-clause initializer-body
 ‌ initializer-head → attributes opt convenience opt init
 ‌ initializer-body → code-block
 
*/
DeclarationPtr Parser::parseInit(const std::vector<AttributePtr>& attrs)
{
    Token token;
    bool convenience = match(L"convenience");
    expect(Keyword::Init, token);
    InitializerDefPtr ret = nodeFactory->createInitializer(token.state);
    ret->setAttributes(attrs);
    if(predicate(L"<"))
    {
        GenericParametersDefPtr params = this->parseGenericParametersDef();
        ret->setGenericParametersDef(params);
    }
    ParametersPtr parameters = parseParameterClause();
    CodeBlockPtr body = parseCodeBlock();
    ret->setConvenience(convenience);
    ret->setParameters(parameters);
    ret->setBody(body);
    return ret;
}
Ejemplo n.º 2
0
void FunctionAnalyzer::visitInit(const InitializerDefPtr& node)
{
    FunctionSymbolPtr init = static_pointer_cast<SymboledInit>(node)->symbol;
    TypePtr funcType = init->getType();
    SCOPED_SET(ctx->currentFunction, funcType);
    {
        InitializationTracer tracer(nullptr, InitializationTracer::Sequence);
        SCOPED_SET(ctx->currentInitializationTracer, &tracer);
        node->getBody()->accept(semanticAnalyzer);
        //check if some stored property is not initialized
        for(const SymbolPtr& storedProp : ctx->currentType->getDeclaredStoredProperties())
        {
            if(!storedProp->hasFlags(SymbolFlagInitialized))
            {
                error(node, Errors::E_PROPERTY_A_NOT_INITIALIZED, L"self." + storedProp->getName());
                return;
            }
        }
    }

    if(node->hasModifier(DeclarationModifiers::Convenience))
    {
        //convenience initializer must call designated initializer in all paths
        InitializerValidator validator(ctx, this);
        node->getBody()->accept(&validator);
        NodePtr refNode = validator.getRefNode() ? validator.getRefNode() : node;
        if(validator.getResult() & InitializerCoverMultiple)
        {
            error(refNode, Errors::E_SELF_INIT_CALLED_MULTIPLE_TIMES_IN_INITIALIZER);
            return;
        }
        switch(validator.getResult())
        {
            case InitializerCoverNoResult:
            case InitializerCoverUnmatched:
            case InitializerCoverPartial:
                error(refNode, Errors::E_SELF_INIT_ISNT_CALLED_ON_ALL_PATHS_IN_DELEGATING_INITIALIZER);
                return;
            default:
                break;
        }

    }
    else
    {
        //designated initializer must call designated initializer if parent type has customized initializer
        bool hasCustomizedInitializer = false;
        if(ctx->currentType->getParentType())
        {
            FunctionOverloadedSymbolPtr inits = ctx->currentType->getDeclaredInitializer();
            if(inits)
            {
                for(const FunctionSymbolPtr& init : *inits)
                {
                    if(!init->getType()->getParameters().empty())
                    {
                        hasCustomizedInitializer = true;
                        break;
                    }
                }
            }
        }
        if(hasCustomizedInitializer)
        {
            InitializerValidator validator(ctx, this);
            node->getBody()->accept(&validator);
            NodePtr refNode = validator.getRefNode() ? validator.getRefNode() : node;
            if(validator.getResult() & InitializerCoverMultiple)
            {
                error(refNode, Errors::E_SUPER_INIT_CALLED_MULTIPLE_TIMES_IN_INITIALIZER);
                return;
            }
            switch(validator.getResult())
            {
                case InitializerCoverNoResult:
                case InitializerCoverUnmatched:
                case InitializerCoverPartial:
                    error(refNode, Errors::E_SUPER_INIT_ISNT_CALLED_BEFORE_RETURNING_FROM_INITIALIZER);
                    return;
                default:
                    break;
            }
        }

    }
}
Ejemplo n.º 3
0
void NodeVisitor::visitInit(const InitializerDefPtr& node)
{
    ACCEPT(node->getBody());
}