Exemplo n.º 1
0
bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast)
{
    unsigned sourceLocation;
    if (ast->class_name)
        sourceLocation = ast->class_name->firstToken();
    else
        sourceLocation = ast->firstToken();

    Name *className = semantic()->check(ast->class_name, _scope);
    ObjCClass *klass = control()->newObjCClass(sourceLocation, className);
    klass->setStartOffset(tokenAt(ast->firstToken()).offset);
    klass->setEndOffset(tokenAt(ast->lastToken()).offset);
    ast->symbol = klass;

    klass->setInterface(ast->interface_token != 0);

    if (ast->category_name) {
        Name *categoryName = semantic()->check(ast->category_name, _scope);
        klass->setCategoryName(categoryName);
    }

    if (ast->superclass) {
        Name *superClassName = semantic()->check(ast->superclass, _scope);
        ObjCBaseClass *superKlass = control()->newObjCBaseClass(ast->superclass->firstToken(), superClassName);
        klass->setBaseClass(superKlass);
    }

    if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
        for (IdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
            NameAST* name = iter->name;
            Name *protocolName = semantic()->check(name, _scope);
            ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
            klass->addProtocol(baseProtocol);
        }
    }

    _scope->enterSymbol(klass);

    int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected);

    if (ast->inst_vars_decl) {
        for (DeclarationListAST *it = ast->inst_vars_decl->instance_variables; it; it = it->next) {
            semantic()->check(it->declaration, klass->members());
        }
    }

    (void) semantic()->switchObjCVisibility(Function::Public);

    for (DeclarationListAST *it = ast->member_declarations; it; it = it->next) {
        semantic()->check(it->declaration, klass->members());
    }

    (void) semantic()->switchObjCVisibility(previousObjCVisibility);

    return false;
}