当前位置: 首页>>代码示例>>C++>>正文


C++ TypePtr::getCategory方法代码示例

本文整理汇总了C++中TypePtr::getCategory方法的典型用法代码示例。如果您正苦于以下问题:C++ TypePtr::getCategory方法的具体用法?C++ TypePtr::getCategory怎么用?C++ TypePtr::getCategory使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在TypePtr的用法示例。


在下文中一共展示了TypePtr::getCategory方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: isKindOf

bool Type::isKindOf(const TypePtr &protocolOrBase) const
{
    assert(protocolOrBase != nullptr);
    if(protocolOrBase->getCategory() != Class && protocolOrBase->getCategory() != Protocol)
        return false;
    auto iter = parents.find(protocolOrBase);
    return iter != parents.end();
}
开发者ID:zhangjunlei26,项目名称:swallow,代码行数:8,代码来源:Type.cpp

示例2: type

USE_SWALLOW_NS


FunctionSymbol::FunctionSymbol(const std::wstring& name, const TypePtr& functionType, const CodeBlockPtr& definition)
:name(name), type(functionType), definition(definition)
{
    assert(functionType);
    assert(functionType->getCategory() == Type::Function);
}
开发者ID:Jornason,项目名称:swallow,代码行数:9,代码来源:FunctionSymbol.cpp

示例3: visitExtension

void DeclarationAnalyzer::visitExtension(const ExtensionDefPtr& node)
{
    if(isLazyDeclared(node))
        return;
    if(ctx->currentFunction || ctx->currentType)
    {
        error(node, Errors::E_A_MAY_ONLY_BE_DECLARED_AT_FILE_SCOPE_1, node->getIdentifier()->getName());
        return;
    }
    //if(parentNode && parentNode->getNodeType() != NodeType::Program)
    if(node->getGenericParametersDef())
    {
        error(node, Errors::E_GENERIC_ARGUMENTS_ARE_NOT_ALLOWED_ON_AN_EXTENSION);
        return;
    }
    //TypePtr type = lookupType(node->getIdentifier());
    SymbolScope* scope = symbolRegistry->getCurrentScope();
    TypePtr type = symbolRegistry->lookupType(node->getIdentifier()->getName());
    if(!type)
        type = scope->getForwardDeclaration(node->getIdentifier()->getName());
    if(!type)
    {
        error(node->getIdentifier(), Errors::E_USE_OF_UNDECLARED_TYPE_1, node->getIdentifier()->getName());
        return;
    }
    ScopeGuard guard(symbolRegistry, type->getScope());

    Type::Category category = type->getCategory();
    if(category == Type::Protocol)
    {
        error(node, Errors::E_PROTOCOL_A_CANNOT_BE_EXTENDED_1, type->getName());
        return;
    }
    if(category != Type::Struct && category != Type::Enum && category != Type::Class)
    {
        error(node, Errors::E_NON_NOMINAL_TYPE_A_CANNOT_BE_EXTENDED_1, node->getIdentifier()->getName());
        return;
    }

    TypePtr extension = Type::newExtension(type);
    symbolRegistry->getFileScope()->addExtension(extension);
    static_pointer_cast<SemanticExtensionDef>(node)->extension = extension;
    SCOPED_SET(ctx->currentType, type);
    SCOPED_SET(ctx->currentExtension, extension);
    for(const DeclarationPtr& decl : *node)
    {
        if(decl->getNodeType() == NodeType::ValueBindings)
        {
            error(node, Errors::E_EXTENSIONS_MAY_NOT_CONTAIN_STORED_PROPERTIES);
            continue;
        }
        decl->accept(this);
    }
}
开发者ID:lexchou,项目名称:swallow,代码行数:54,代码来源:DeclarationAnalyzer_Type.cpp

示例4: canAssignTo

bool Type::canAssignTo(const TypePtr &type) const
{
    if(type == nullptr)
        return false;
    TypePtr self = this->self();
    if(equals(self, type))
        return true;
    if(type->getCategory() == Protocol || type->getCategory() == Class)
    {
        if(this->category == Type::Specialized)
            self = innerType;
        if(self->parents.find(type) != parents.end())
        {
            return true;
        }
        return false;
    }
    /*
    if(type->getCategory() != category)
        return false;
    if(category == Tuple)
    {
        //In tuple type, each element type must can be assigned to corresponding element type in given argument
        if(elementTypes.size() != type->elementTypes.size())
            return false;
        auto iter1 = elementTypes.begin();
        auto iter2 = type->elementTypes.begin();
        for(; iter1 != elementTypes.end(); iter1++, iter2++)
        {
            if(!(*iter1)->canAssignTo(*iter2))
            {
                return false;
            }
        }
    }
    */
    return equals(self, type);
}
开发者ID:zhangjunlei26,项目名称:swallow,代码行数:38,代码来源:Type.cpp

示例5: checkTupleDefinition

void SemanticAnalyzer::checkTupleDefinition(const TuplePtr& tuple, const ExpressionPtr& initializer)
{
    //this is a tuple definition, the corresponding declared type must be a tuple type
    TypeNodePtr declaredType = tuple->getDeclaredType();
    TypePtr type = lookupType(declaredType);
    if(!type)
    {
        error(tuple, Errors::E_USE_OF_UNDECLARED_TYPE_1, toString(declaredType));
        return;
    }
    if(!(type->getCategory() == Type::Tuple))
    {
        //tuple definition must have a tuple type definition
        error(tuple, Errors::E_TUPLE_PATTERN_MUST_MATCH_TUPLE_TYPE_1, toString(declaredType));
        return;
    }
    if(tuple->numElements() != type->numElementTypes())
    {
        //tuple pattern has the wrong length for tuple type '%'
        error(tuple, Errors::E_TUPLE_PATTERN_MUST_MATCH_TUPLE_TYPE_1, toString(declaredType));
        return;
    }
    //check if initializer has the same type with the declared type
    if(initializer)
    {
        TypePtr valueType = evaluateType(initializer);
        if(valueType && !Type::equals(valueType, type))
        {
            //tuple pattern has the wrong length for tuple type '%'
            //tuple types '%0' and '%1' have a different number of elements (%2 vs. %3)
            wstring expectedType = type->toString();
            wstring got = toString(valueType->numElementTypes());
            wstring expected = toString(type->numElementTypes());
            error(initializer, Errors::E_TUPLE_TYPES_HAVE_A_DIFFERENT_NUMBER_OF_ELEMENT_4, toString(declaredType), expectedType, got, expected);
            return;
        }
    }


    for(const PatternPtr& p : *tuple)
    {
        NodeType nodeType = p->getNodeType();
        if(nodeType != NodeType::Identifier)
        {

        }

    }
}
开发者ID:lexchou,项目名称:swallow,代码行数:49,代码来源:SemanticAnalyzer_Variables.cpp

示例6: dumpCompilerResults

TEST(TestEnumeration, Declaration)
{
    SEMANTIC_ANALYZE(L"enum CompassPoint { \n"
            L"case North\n"
            L"case South\n"
            L"case East\n"
            L"case West\n"
            L"}");
    dumpCompilerResults(compilerResults);
    ASSERT_EQ(0, compilerResults.numResults());
    TypePtr CompassPoint;
    ASSERT_NOT_NULL(CompassPoint = dynamic_pointer_cast<Type>(scope->lookup(L"CompassPoint")));
    ASSERT_EQ(Type::Enum, CompassPoint->getCategory());

}
开发者ID:healerkx,项目名称:swallow,代码行数:15,代码来源:TestEnumeration.cpp

示例7: verifyProtocolConform

/*!
 * Verify if the specified type conform to the given protocol
 */
bool DeclarationAnalyzer::verifyProtocolConform(const TypePtr& type, bool supressError)
{
    if(type->getCategory() == Type::Protocol)
        return true;//do not perform protocol conform on protocol type
    int idx = 0;
    TypeBuilderPtr type2 = static_pointer_cast<TypeBuilder>(type);
    vector<int>& protocolFlags = type2->getProtocolFlags();
    for(const TypePtr& protocol : type->getProtocols())
    {
        //TODO check if the protocol is checked
        if(protocolFlags[idx] == 0)
        {
            bool success = verifyProtocolConform(type, protocol, supressError);
            if(success)
            {
                //TODO: mark the protocol is checked
                protocolFlags[idx] = 1;
            }
        }
        idx++;
    }
    return true;
}
开发者ID:songpeace,项目名称:swallow,代码行数:26,代码来源:DeclarationAnalyzer_ProtocolConform.cpp

示例8: defineType

TypePtr DeclarationAnalyzer::defineType(const std::shared_ptr<TypeDeclaration>& node)
{
    TypeIdentifierPtr id = node->getIdentifier();

    //Analyze the type's category
    Type::Category category;
    switch(node->getNodeType())
    {
        case NodeType::Enum:
            category = Type::Enum;
            break;
        case NodeType::Class:
            category = Type::Class;
            break;
        case NodeType::Struct:
            category = Type::Struct;
            break;
        case NodeType::Protocol:
            category = Type::Protocol;
            break;
        default:
            assert(0 && "Impossible to execute here.");
    }

    //it's inside the type's scope, so need to access parent scope;

    //prepare for generic types
    GenericParametersDefPtr genericParams = node->getGenericParametersDef();

    //check if it's defined as a nested type
    if(ctx->currentType)
    {
        if(genericParams)
        {
            error(node, Errors::E_GENERIC_TYPE_A_NESTED_IN_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
            return nullptr;
        }
        if(ctx->currentType->isGenericType())
        {
            error(node, Errors::E_TYPE_A_NESTED_IN_GENERIC_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
            return nullptr;
        }
    }
    
    //register this type
    SymbolScope* currentScope = symbolRegistry->getCurrentScope();
    TypeBuilderPtr type = static_pointer_cast<TypeBuilder>(currentScope->getForwardDeclaration(id->getName()));
    S_ASSERT(type == nullptr);
    type = static_pointer_cast<TypeBuilder>(Type::newType(id->getName(), category));
    currentScope->addForwardDeclaration(type);
    TypeDeclarationPtr tnode = dynamic_pointer_cast<TypeDeclaration>(node);
    type->setReference(tnode);    
    if(tnode)
        tnode->setType(type);

    assert(type != nullptr);
    assert(type->getCategory() == category);
    //prepare for generic
    if(!type->getGenericDefinition() && node->getGenericParametersDef())
    {
        GenericParametersDefPtr genericParams = node->getGenericParametersDef();
        GenericDefinitionPtr generic = prepareGenericTypes(genericParams);
        generic->registerTo(type->getScope());
        type->setGenericDefinition(generic);
    }
    
    if(node->hasModifier(DeclarationModifiers::Final))
        type->setFlags(SymbolFlagFinal, true);
    static_pointer_cast<TypeBuilder>(type)->setModuleName(ctx->currentModule->getName());
    ctx->allTypes.push_back(type);
    
    //check inheritance clause
    {
        TypePtr parent = nullptr;
        bool first = true;

        ScopeGuard scope(symbolRegistry, type->getScope());
        SCOPED_SET(ctx->currentType, type);
        for(const TypeIdentifierPtr& parentType : node->getParents())
        {
            parentType->accept(this);
            if(first)
                declareImmediately(parentType->getName());
            TypePtr ptr = resolveType(parentType, true);
            Type::Category pcategory = ptr->getCategory();
            if(pcategory == Type::Specialized)
                pcategory = ptr->getInnerType()->getCategory();
            if(pcategory == Type::Class && category == Type::Class)
            {
                if(!first)
                {
                    //only the first type can be class type
                    error(parentType, Errors::E_SUPERCLASS_MUST_APPEAR_FIRST_IN_INHERITANCE_CLAUSE_1, toString(parentType));
                    return nullptr;
                }
                parent = ptr;
                if(parent->hasFlags(SymbolFlagFinal))
                {
                    error(parentType, Errors::E_INHERITANCE_FROM_A_FINAL_CLASS_A_1, parentType->getName());
                    return nullptr;
//.........这里部分代码省略.........
开发者ID:lexchou,项目名称:swallow,代码行数:101,代码来源:DeclarationAnalyzer_Type.cpp

示例9: visitEnum

void DeclarationAnalyzer::visitEnum(const EnumDefPtr& node)
{
    if(isLazyDeclared(node))
        return;
    TypeBuilderPtr type = static_pointer_cast<TypeBuilder>(getOrDefineType(node));
    ScopeGuard scope(symbolRegistry, type->getScope());
    SCOPED_SET(ctx->currentType, type);
    SCOPED_SET(ctx->currentExtension, nullptr);
    SCOPED_SET(ctx->currentFunction, nullptr);


    GlobalScope* global = symbolRegistry->getGlobalScope();
    SymbolScope* local = symbolRegistry->getCurrentScope();
    //check if it's raw value enum
    bool isRawValues = false;
    if(node->numParents() > 0)
    {
        TypePtr firstParent = lookupType(node->getParent(0));
        if(firstParent)
        {
            Type::Category  category = firstParent->getCategory();
            isRawValues = category == Type::Struct || category == Type::Enum || category == Type::Aggregate || category == Type::Class;
            if(isRawValues)
                type->setParentType(firstParent);
        }
    }

    //initialize enum's cases
    if(isRawValues)
    {
        if(!node->numCases())
        {
            error(node, Errors::E_ENUM_WITH_NO_CASES_CANNOT_DECLARE_A_RAW_TYPE);
            return;
        }
        //Add RawRepresentable protocol if it's not implemented
        if(!type->canAssignTo(global->RawRepresentable()))
        {
            makeRawRepresentable(type, global);
        }

        TypePtr rawType = type->getParentType();
        assert(rawType != nullptr);
        bool integerConvertible = rawType->canAssignTo(global->IntegerLiteralConvertible());
        for(auto c : node->getCases())
        {
            if(!c.value && !integerConvertible)
            {
                //Enum cases require explicit raw values when the raw type is not integer literal convertible
                error(node, Errors::E_ENUM_CASES_REQUIRE_EXPLICIT_RAW_VALUES_WHEN_THE_RAW_TYPE_IS_NOT_INTEGER_LITERAL_CONVERTIBLE);
                return;
            }
            if(c.value)
            {
                if(dynamic_pointer_cast<TupleType>(c.value))
                {
                    error(node, Errors::E_ENUM_WITH_RAW_TYPE_CANNOT_HAVE_CASES_WITH_ARGUMENTS);
                    return;
                }
            }
            type->addEnumCase(c.name, global->Void());
            //register it to scope
            local->addSymbol(SymbolPlaceHolderPtr(new SymbolPlaceHolder(c.name, type, SymbolPlaceHolder::R_PARAMETER, SymbolFlagReadable | SymbolFlagMember | SymbolFlagStatic | SymbolFlagInitialized)));
        }
    }
    else
    {
        //it's an associated-values enum
        for(auto c : node->getCases())
        {
            TypePtr associatedType = global->Void();
            if(c.value)
            {
                TypeNodePtr typeNode = dynamic_pointer_cast<TypeNode>(c.value);
                if(!typeNode)
                {
                    error(node, Errors::E_ENUM_CASE_CANNOT_HAVE_A_RAW_VALUE_IF_THE_ENUM_DOES_NOT_HAVE_A_RAW_TYPE);
                    return;
                }
                assert(typeNode != nullptr);
                associatedType = resolveType(typeNode, true);
            }
            type->addEnumCase(c.name, associatedType);
            if(associatedType == global->Void())
                local->addSymbol(SymbolPlaceHolderPtr(new SymbolPlaceHolder(c.name, type, SymbolPlaceHolder::R_PARAMETER, SymbolFlagReadable | SymbolFlagMember | SymbolFlagStatic | SymbolFlagInitialized)));
        }
    }
    //check member declaration of enum
    {
        SCOPED_SET(ctx->flags, (ctx->flags & (~SemanticContext::FLAG_PROCESS_IMPLEMENTATION)) | SemanticContext::FLAG_PROCESS_DECLARATION);
        for (const DeclarationPtr &decl : *node)
        {
            bool isStatic = decl->hasModifier(DeclarationModifiers::Class) || decl->hasModifier(DeclarationModifiers::Static);
            if (!isStatic && (decl->getNodeType() == NodeType::ValueBindings))
            {
                error(node, Errors::E_ENUMS_MAY_NOT_CONTAIN_STORED_PROPERTIES);
                continue;
            }
            decl->accept(this);
        }
//.........这里部分代码省略.........
开发者ID:lexchou,项目名称:swallow,代码行数:101,代码来源:DeclarationAnalyzer_Type.cpp

示例10: prepareDefaultInitializers

void DeclarationAnalyzer::prepareDefaultInitializers(const TypePtr& type)
{

    /*
    Rule of initializers for class/structure:
    1) If no custom initializers, compiler will prepare one or two initializers:
        1.1) A default initializer with no arguments if all let/var fields are defined with a default value
        1.2) Skip this rule if it's a class. A default initializer with all let/var fields as initializer's parameters with the same external name,
            the order of the parameters are the exactly the same as them defined in structure
    2) Compiler will not generate initializers if there's custom initializers
    3) Convenience initializers will not be counted
     */
    SCOPED_SET(ctx->currentType, type);
    FunctionOverloadedSymbolPtr initializers = type->getDeclaredInitializer();
    int designatedInitializers = numDesignatedInitializers(initializers);
    if(designatedInitializers == 0)
    {
        bool createDefaultInit = true;
        vector<Parameter> initParams;
        if (type->getCategory() == Type::Struct)
        {
            //check all fields if they all have initializer
            for (auto sym : type->getDeclaredStoredProperties())
            {
                SymbolPlaceHolderPtr s = dynamic_pointer_cast<SymbolPlaceHolder>(sym);
                if (!s || sym->hasFlags(SymbolFlagTemporary))
                    continue;
                initParams.push_back(Parameter(sym->getName(), false, sym->getType()));
                //do not create default init if there's a variable has no initializer
                if (!s->hasFlags(SymbolFlagHasInitializer))
                    createDefaultInit = false;
            }
        }
        GlobalScope* global = symbolRegistry->getGlobalScope();
        bool initCreated = false;
        if (createDefaultInit)
        {
            //apply rule 1
            std::vector<Parameter> params;
            TypePtr initType = Type::newFunction(params, global->Void(), false);
            initType->setFlags(SymbolFlagInit, true);
            FunctionSymbolPtr initializer(new FunctionSymbol(L"init", initType, FunctionRoleInit, nullptr));
            declarationFinished(initializer->getName(), initializer, nullptr);
            initCreated = true;
        }
        if (type->getCategory() == Type::Struct && !initParams.empty())
        {
            TypePtr initType = Type::newFunction(initParams, global->Void(), false);
            initType->setFlags(SymbolFlagInit, true);
            FunctionSymbolPtr initializer(new FunctionSymbol(L"init", initType, FunctionRoleInit, nullptr));
            declarationFinished(initializer->getName(), initializer, nullptr);
            initCreated = true;
        }
        //make all stored properties initialized after the default initializer created
        if(initCreated)
        {
            for(const SymbolPtr& s : type->getDeclaredStoredProperties())
            {
                s->setFlags(SymbolFlagInitialized, true);
            }
        }

    }
    //inherit designated initializers from parent type
    if(type->getParentType() && type->getCategory() == Type::Class)
    {
        FunctionOverloadedSymbolPtr initializers = type->getDeclaredInitializer();

        TypeBuilderPtr builder = static_pointer_cast<TypeBuilder>(type);
        if(!initializers)
        {
            initializers = FunctionOverloadedSymbolPtr(new FunctionOverloadedSymbol(L"init"));
            builder->setInitializer(initializers);
        }
        TypePtr parent = type->getParentType();
        FunctionOverloadedSymbolPtr baseInitializers = parent->getDeclaredInitializer();
        if(baseInitializers)
        {
            for(const FunctionSymbolPtr& baseInitializer : *baseInitializers)
            {
                //skip convenience initializer
                if(baseInitializer->hasFlags(SymbolFlagConvenienceInit))
                    continue;
                //check if it's defined in current type
                TypePtr initType = baseInitializer->getType();
                FunctionSymbolPtr initializer = initializers->lookupByType(initType);
                if(!initializer)
                {
                    //this initializer exists in base type, but not in current type
                    //so we need to create it in current type
                    initializer = FunctionSymbolPtr(new FunctionSymbol(L"init", initType, FunctionRoleInit, nullptr));
                    //initializers->add(initializer);
                    builder->addMember(initializer);
                }
                
            }
        }
    }
}
开发者ID:lexchou,项目名称:swallow,代码行数:99,代码来源:DeclarationAnalyzer_Type.cpp

示例11: checkTypeConform

/*!
 * Check if the actual type can conform to requirement type where actual type is declared inside an owner type
 */
static bool checkTypeConform(const TypePtr& ownerType, TypePtr requirementType, const TypePtr& actualType)
{
    assert(actualType != nullptr);
    if(requirementType->getCategory() == Type::Alias)
    {
        wstring name = requirementType->getName();
        if(name == L"Self")
            requirementType = ownerType;
        else
            requirementType = ownerType->getAssociatedType(name);
        if(requirementType != nullptr)
            requirementType = requirementType->resolveAlias();
        if(requirementType == nullptr && actualType && actualType->getCategory() != Type::Alias)
        {
            //do typealias infer, the required type is not existing in owner type, we implicitly declare it as associated type
            requirementType = actualType;
            TypeBuilderPtr type = static_pointer_cast<TypeBuilder>(ownerType);
            type->addMember(name, actualType);
        }
        if(requirementType == nullptr)
            return false;
    }
    Type::Category category = requirementType->getCategory();
    if(category != actualType->getCategory())
        return false;
    switch(category)
    {
    case Type::Class:
    case Type::Struct:
    case Type::Protocol:
    case Type::Enum:
    case Type::Aggregate:
        return actualType == requirementType;
    case Type::GenericParameter:
        return actualType->getName() == requirementType->getName();
    case Type::MetaType:
        return checkTypeConform(ownerType, requirementType->getInnerType(), actualType->getInnerType());
    case Type::Tuple:
    {
        if(actualType->numElementTypes() != requirementType->numElementTypes())
            return false;
        int num = actualType->numElementTypes();
        for(int i = 0; i < num; i++)
        {
            TypePtr req = requirementType->getElementType(i);
            TypePtr act = actualType->getElementType(i);
            if(!checkTypeConform(ownerType, req, act))
                return false;
        }
        return true;
    }
    case Type::Function:
    {
        size_t num = requirementType->getParameters().size();
        if(num != actualType->getParameters().size())
            return false;
        if(!checkTypeConform(ownerType, requirementType->getReturnType(), actualType->getReturnType()))
            return false;
        auto iter = requirementType->getParameters().begin();
        auto iter2 = actualType->getParameters().begin();
        for(; iter != requirementType->getParameters().end(); iter++, iter2++)
        {
            if(iter->name != iter2->name)
                return false;
            if(iter->inout != iter2->inout)
                return false;
            TypePtr req = iter->type;
            TypePtr act = iter2->type;
            if(!checkTypeConform(ownerType, req, act))
                return false;
        }
        return true;
    }
    case Type::Specialized:
    {
        if(!Type::equals(requirementType->getInnerType(), actualType->getInnerType()))
            return false;
        GenericArgumentPtr greq = requirementType->getGenericArguments();
        GenericArgumentPtr gact = actualType->getGenericArguments();
        if(greq->size() != gact->size())
            return false;
        size_t size = greq->size();
        //TODO: check for parent generic arguments
        for(size_t i = 0; i < size; i++)
        {
            TypePtr req = greq->get(i);
            TypePtr act = gact->get(i);
            if(!checkTypeConform(ownerType, req, act))
                return false;
        }
        return true;

    }
    default:
        assert(0 && "Unsupported type category");
        return false;

//.........这里部分代码省略.........
开发者ID:songpeace,项目名称:swallow,代码行数:101,代码来源:DeclarationAnalyzer_ProtocolConform.cpp

示例12: defineType

TypePtr DeclarationAnalyzer::defineType(const std::shared_ptr<TypeDeclaration>& node)
{
    TypeIdentifierPtr id = node->getIdentifier();
    SymbolScope* scope = NULL;
    TypePtr type;

    //Analyze the type's category
    Type::Category category;
    switch(node->getNodeType())
    {
        case NodeType::Enum:
            category = Type::Enum;
            break;
        case NodeType::Class:
            category = Type::Class;
            break;
        case NodeType::Struct:
            category = Type::Struct;
            break;
        case NodeType::Protocol:
            category = Type::Protocol;
            break;
        default:
            assert(0 && "Impossible to execute here.");
    }

    //it's inside the type's scope, so need to access parent scope;
    SymbolScope* typeScope = symbolRegistry->getCurrentScope();
    SymbolScope* currentScope = typeScope->getParentScope();

    //check if this type is already defined
    symbolRegistry->lookupType(id->getName(), &scope, &type);
    if(type && scope == currentScope)
    {
        //invalid redeclaration of type T
        error(node, Errors::E_INVALID_REDECLARATION_1, id->getName());
        return nullptr;
    }
    //prepare for generic types
    GenericDefinitionPtr generic;
    GenericParametersDefPtr genericParams = node->getGenericParametersDef();

    //check if it's defined as a nested type
    if(ctx->currentType)
    {
        if(genericParams)
        {
            error(node, Errors::E_GENERIC_TYPE_A_NESTED_IN_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
            return nullptr;
        }
        if(ctx->currentType->isGenericType())
        {
            error(node, Errors::E_TYPE_A_NESTED_IN_GENERIC_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
            return nullptr;
        }
    }

    if(genericParams)
    {
        generic = prepareGenericTypes(genericParams);
        generic->registerTo(typeScope);
    }

    //check inheritance clause
    TypePtr parent = nullptr;
    std::vector<TypePtr> protocols;
    bool first = true;

    for(const TypeIdentifierPtr& parentType : node->getParents())
    {
        parentType->accept(semanticAnalyzer);
        TypePtr ptr = this->lookupType(parentType);
        if(ptr->getCategory() == Type::Class && category == Type::Class)
        {
            if(!first)
            {
                //only the first type can be class type
                error(parentType, Errors::E_SUPERCLASS_MUST_APPEAR_FIRST_IN_INHERITANCE_CLAUSE_1, toString(parentType));
                return nullptr;
            }
            parent = ptr;
            if(parent->hasFlags(SymbolFlagFinal))
            {
                error(parentType, Errors::E_INHERITANCE_FROM_A_FINAL_CLASS_A_1, parentType->getName());
                return nullptr;
            }
        }
        else if(category == Type::Enum && ptr->getCategory() != Type::Protocol)
        {

            if(parent)//already has a raw type
            {
                error(parentType, Errors::E_MULTIPLE_ENUM_RAW_TYPES_A_AND_B_2, parent->toString(), ptr->toString());
                return nullptr;
            }
            if(!first)
            {
                error(parentType, Errors::E_RAW_TYPE_A_MUST_APPEAR_FIRST_IN_THE_ENUM_INHERITANCE_CLAUSE_1, ptr->toString());
                return nullptr;
            }
//.........这里部分代码省略.........
开发者ID:voidException,项目名称:swallow,代码行数:101,代码来源:DeclarationAnalyzer_Type.cpp

示例13: visitStruct

void DeclarationAnalyzer::visitStruct(const StructDefPtr& node)
{
    TypePtr type = defineType(node);
    SCOPED_SET(ctx->currentType, type);
    visitDeclaration(node);
    //prepare default initializers
    this->prepareDefaultInitializers(type);
    //Type verification and typealias inference

    for(auto entry : type->getAllParents())
    {
        TypePtr parent = entry.first;
        if(parent->getCategory() != Type::Protocol || !(parent->containsAssociatedType() || parent->containsSelfType()))
            continue;
        //this parent is a protocol that contains associated type, now validate protocol's methods and infer the types out
        std::map<std::wstring, TypePtr> associatedTypes;
        //collect all defined associated types
        for(auto entry : parent->getAssociatedTypes())
        {
            TypePtr type = entry.second->unwrap();
            if(type->getCategory() != Type::Alias)
                associatedTypes.insert(make_pair(entry.first, type));
        }
        if(parent->containsSelfType())
            associatedTypes.insert(make_pair(L"Self", type));

        for(const FunctionOverloadedSymbolPtr& funcs : parent->getDeclaredFunctions())
        {
            for(const FunctionSymbolPtr& expectedFunc : *funcs)
            {
                TypePtr expectedType = expectedFunc->getType();
                assert(expectedType != nullptr);
                bool matched = false;
                //get all methods with the same name, and check their signature one by one
                vector<SymbolPtr> funcs;
                bool staticMember = expectedFunc->hasFlags(SymbolFlagStatic);
                semanticAnalyzer->getMethodsFromType(type, expectedFunc->getName(), (MemberFilter)((staticMember ? FilterStaticMember : 0) | (FilterLookupInExtension | FilterRecursive)), funcs);
                for(const SymbolPtr& func : funcs)
                {
                    TypePtr actualType = func->getType();
                    assert(actualType != nullptr);
                    if(expectedType->canSpecializeTo(actualType, associatedTypes))
                    {
                        matched = true;
                        break;
                    }
                }
                if(!matched)
                {
                    //no matched function
                    error(node, Errors::E_TYPE_DOES_NOT_CONFORM_TO_PROTOCOL_UNIMPLEMENTED_FUNCTION_3, type->getName(), parent->getName(), expectedFunc->getName());
                    return;
                }
            }
        }
        //now make types infered above visible

        for(auto entry : associatedTypes)
        {
            if(entry.first == L"Self")
                continue;
            static_pointer_cast<TypeBuilder>(type)->addMember(entry.first, entry.second);
        }
    }

    verifyProtocolConform(type);
    validateDeclarationModifiers(node);



    visitImplementation(node);
}
开发者ID:voidException,项目名称:swallow,代码行数:72,代码来源:DeclarationAnalyzer_Type.cpp

示例14: validateTupleTypeDeclaration

void SemanticAnalyzer::validateTupleTypeDeclaration(const PatternPtr& name, const TypePtr& declType, const TypePtr& initType)
{
    switch(name->getNodeType())
    {
        case NodeType::Identifier:
        {
            if(initType && declType && !initType->canAssignTo(declType))
            {
                error(name, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, initType->toString(), declType->toString());
            }
            break;
        }
        case NodeType::TypedPattern:
        {
            TypedPatternPtr pat = static_pointer_cast<TypedPattern>(name);
            assert(pat->getDeclaredType());
            TypePtr nameType = lookupType(pat->getDeclaredType());
            assert(nameType != nullptr);
            if(declType && !Type::equals(nameType, declType))
            {
                error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
                abort();
                return;
            }

            break;
        }
        case NodeType::Tuple:
        {
            TuplePtr tuple = static_pointer_cast<Tuple>(name);
            if(declType)
            {
                if((declType->getCategory() != Type::Tuple) || (tuple->numElements() != declType->numElementTypes()))
                {
                    error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
                    abort();
                    return;
                }
            }
            int elements = tuple->numElements();
            for(int i = 0; i < elements; i++)
            {
                PatternPtr element = tuple->getElement(i);
                TypePtr elementDecl = declType ? declType->getElementType(i) : nullptr;
                TypePtr elementInit = initType ? initType->getElementType(i) : nullptr;
                validateTupleTypeDeclaration(element, elementDecl, elementInit);
            }
            break;
        }
        case NodeType::ValueBindingPattern:
            break;
        case NodeType::EnumCasePattern:
        {
            
            break;
        }
        case NodeType::TypeCase:
        case NodeType::TypeCheck:
        default:
            error(name, Errors::E_EXPECT_TUPLE_OR_IDENTIFIER);
            break;
    }
    
}
开发者ID:lexchou,项目名称:swallow,代码行数:64,代码来源:SemanticAnalyzer_Variables.cpp


注:本文中的TypePtr::getCategory方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。