Example #1
0
void FunctionAnalyzer::visitSubscript(const SubscriptDefPtr &node)
{
    //TypeInference
    ParametersNodePtr parameters = node->getParameters();
    TypePtr retType = declarationAnalyzer->resolveType(node->getReturnType(), true);

    TypePtr type = declarationAnalyzer->resolveType(node->getReturnType(), true);
    assert(type != nullptr);
    std::vector<Parameter> params;
    for (const ParameterNodePtr &param : *node->getParameters())
    {
        wstring name = param->isShorthandExternalName() ? param->getLocalName() : param->getExternalName();
        TypePtr paramType = declarationAnalyzer->resolveType(param->getDeclaredType(), true);
        params.push_back(Parameter(name, param->isInout(), paramType));
        //verify index's access level
        declarationAnalyzer->verifyAccessLevel(node, paramType, DeclarationTypeSubscript, ComponentTypeIndex);
    }
    //verify element type's access level
    declarationAnalyzer->verifyAccessLevel(node, type, DeclarationTypeSubscript, ComponentTypeType);


    //process getter
    visitAccessor(node->getGetter(), parameters, nullptr, node->getModifiers());
    //process setter
    wstring setterName = L"newValue";
    if (!node->getSetterName().empty())
        setterName = node->getSetterName();
    SymbolPlaceHolderPtr setter(new SymbolPlaceHolder(setterName, retType, SymbolPlaceHolder::R_PARAMETER, SymbolFlagReadable | SymbolFlagInitialized));
    visitAccessor(node->getSetter(), parameters, setter, node->getModifiers());
}
/*
 “GRAMMAR OF A SUBSCRIPT DECLARATION
 
 ‌ subscript-declaration → subscript-head subscript-result code-block
 ‌ subscript-declaration → subscript-head subscript-result getter-setter-block
 ‌ subscript-declaration → subscript-head subscript-result getter-setter-keyword-block
 ‌ subscript-head → attributes opt subscript parameter-clause
 ‌ subscript-result → ->attributes opt type
 ”
*/
DeclarationPtr Parser::parseSubscript(const std::vector<AttributePtr>& attrs)
{
    Token token;
    expect(Keyword::Subscript, token);
    ParametersPtr params = parseParameterClause();
    expect(L"->");
    Attributes typeAttrs;
    parseAttributes(typeAttrs);
    TypeNodePtr retType = parseType();
    SubscriptDefPtr ret = nodeFactory->createSubscript(token.state);
    ret->setAttributes(attrs);
    ret->setParameters(params);
    ret->setReturnType(retType);
    ret->setReturnTypeAttributes(typeAttrs);
    
    if(flags & UNDER_PROTOCOL)
    {
        expect(L"{");
        std::pair<CodeBlockPtr, CodeBlockPtr> accessors = parseGetterSetterKeywordBlock();
        expect(L"}");
        ret->setGetter(accessors.first);
        ret->setSetter(accessors.second);
    }
    else
    {
        Token token;
        TokenizerState s = tokenizer->save();
        expect(L"{");
        expect_next(token);
        restore(token);
        if(token.getKeyword() == Keyword::Set || token.getKeyword() == Keyword::Get)
        {
            std::pair<CodeBlockPtr, std::pair<std::wstring, CodeBlockPtr> > accessors = parseGetterSetterBlock();
            ret->setGetter(accessors.first);
            ret->setSetter(accessors.second.second);
            ret->setSetterName(accessors.second.first);
            expect(L"}");
        }
        else
        {
            tokenizer->restore(s);
            CodeBlockPtr cb = parseCodeBlock();
            ret->setGetter(cb);
        }
    }
    return ret;
}
Example #3
0
void NodeVisitor::visitSubscript(const SubscriptDefPtr& node)
{
    ACCEPT(node->getGetter());
    ACCEPT(node->getSetter());
}