Alien-SmokeQt

 view release on metacpan or  search on metacpan

generator/generatorvisitor.cpp  view on Meta::CPAN

    do {
        nspace.push_back(name);
        QString n = nspace.join("::");
        returnOnExistence(n);
        nspace.pop_back();
        if (!nspace.isEmpty())
            nspace.pop_back();
    } while (!nspace.isEmpty());

    // check for nested classes
    for (int i = klass.count() - 1; i >= 0; i--) {
        QString _name = klass[i]->toString() + "::" + name;
        returnOnExistence(_name);
        BasicTypeDeclaration* decl = resolveTypeInSuperClasses(klass[i], name);
        if (decl)
            return decl;
    }

    // maybe it's just 'there'
    returnOnExistence(name);

    // check for the name in any of the namespaces included by 'using namespace'
    foreach (const QStringList& list, usingNamespaces) {
        foreach (const QString& string, list) {
            QString cname = string + "::" + name;
            returnOnExistence(cname);
        }
    }

    QStringList parts = name.split("::");
    if (parts.count() > 1) {
        // try to resolve the first part - if that works simply append the last part.
        BasicTypeDeclaration* decl = resolveType(parts.takeFirst());
        if (!decl)
            return 0;
        parts.prepend(decl->toString());
        name = parts.join("::");
        returnOnExistence(name);
    } else {
        // maybe it's an enum value (as used for template args in phonon)
        
        // look through all the enums of the parent classes
        if (!klass.isEmpty()) {
            const Class* clazz = klass.top();
            while (clazz) {
                foreach (BasicTypeDeclaration* decl, klass.top()->children()) {
                    Enum* e = 0;
                    if (!(e = dynamic_cast<Enum*>(decl)))
                        continue;
                    foreach (const EnumMember& member, e->members()) {
                        if (member.name() == name) {
                            name.prepend(klass.top()->toString() + "::");
                            return 0;
                        }
                    }
                }
                clazz = clazz->parent();
            }
        }
        
        // look through all global enums in our namespace
        QStringList nspace = this->nspace;
        do {
            QString n = nspace.join("::");
            foreach (const Enum& e, enums.values()) {
                if (e.parent())
                    continue;
                
                if (e.nameSpace() == n) {
                    foreach (const EnumMember& member, e.members()) {
                        if (member.name() == name) {
                            name.prepend(n + "::");
                            return 0;
                        }
                    }
                }
            }
            if (!nspace.isEmpty())
                nspace.pop_back();
        } while (!nspace.isEmpty());
    }

    return 0;
}

QString GeneratorVisitor::resolveEnumMember(const QString& name)
{
    QString parent, member;
    int idx = -1;
    if ((idx = name.lastIndexOf("::")) != -1) {
        parent = name.mid(0, idx);
        member = name.mid(idx + 2);
    } else {
        member = name;
    }
    return resolveEnumMember(parent, member);
}

// TODO: This doesn't look for the enum in superclasses and parent classes yet - but it suffices for the moment.
QString GeneratorVisitor::resolveEnumMember(const QString& parent, const QString& name)
{
    // is 'parent' a know class?
    if (!parent.isEmpty()) {
        BasicTypeDeclaration* decl = resolveType(parent);
        if (decl)
            return decl->toString() + "::" + name;
    }
    
    // doesn't seem to be a class, so it's probably a part of a namespace name
    QStringList nspace = this->nspace;
    do {
        QString n = nspace.join("::");
        if (!n.isEmpty() && !parent.isEmpty()) n += "::";
        n += parent;
        
        foreach (const Enum& e, enums.values()) {
            if (e.parent())
                continue;
            
            if (e.nameSpace() == n) {
                foreach (const EnumMember& member, e.members()) {

generator/generatorvisitor.cpp  view on Meta::CPAN

            returnType = Type::registerType(t);
        } else if (isDestructor) {
            // destructors don't have a return type.. so return void
            returnType = const_cast<Type*>(Type::Void);
        } else if (nc->isCastOperator()) {
            returnType = Type::registerType(nc->castType());
        }
        currentMethod = Method(klass.top(), declName, returnType, access.top());
        currentMethod.setIsConstructor(isConstructor);
        currentMethod.setIsDestructor(isDestructor);
        currentMethod.setIsSignal(inSignals.top());
        currentMethod.setIsSlot(inSlots.top());
        // build parameter list
        inMethod = true;
        visit(node->parameter_declaration_clause);
        inMethod = false;
        QPair<bool, bool> cv = parseCv(node->fun_cv);
        // const & volatile modifiers
        currentMethod.setIsConst(cv.first);
        
        if (isVirtual) currentMethod.setFlag(Method::Virtual);
        if (hasInitializer) currentMethod.setFlag(Method::PureVirtual);
        if (isStatic) currentMethod.setFlag(Method::Static);
        if (isExplicit) currentMethod.setFlag(Method::Explicit);

        // the class already contains the method (probably imported by a 'using' statement)
        if (klass.top()->methods().contains(currentMethod)) {
            return;
        }

        // Q_PROPERTY accessor?
        if (ParserOptions::qtMode) {
            foreach (const QProperty& prop, q_properties.top()) {
                if (   (currentMethod.parameters().count() == 0 && prop.read == currentMethod.name() && currentMethod.type()->toString().endsWith(prop.type)
                       && (currentMethod.type()->pointerDepth() == 1) == prop.isPtr)    // READ accessor?
                    || (currentMethod.parameters().count() == 1 && prop.write == currentMethod.name()
                       && currentMethod.parameters()[0].type()->toString().remove(QRegExp("^const ")).remove(QRegExp("\\&$")).endsWith(prop.type)
                       && (currentMethod.parameters()[0].type()->pointerDepth() == 1) == prop.isPtr))   // or WRITE accessor?
                {
                    currentMethod.setIsQPropertyAccessor(true);
                }
            }
        }

        if (node->exception_spec) {
            currentMethod.setHasExceptionSpec(true);
            if (node->exception_spec->type_ids) {
                const ListNode<TypeIdAST*>* it = node->exception_spec->type_ids->toFront(), *end = it;
                do {
                    tc->run(it->element->type_specifier, it->element->declarator);
                    currentMethod.appendExceptionType(tc->type());
                    it = it->next;
                } while (it != end);
            }
        }

        klass.top()->appendMethod(currentMethod);
        return;
    }
    
    // global function
    if (node->parameter_declaration_clause && !inMethod && !inClass) {
        if (!declName.contains("::")) {
            Type* returnType = currentTypeRef;
            currentFunction = Function(declName, nspace.join("::"), returnType);
            currentFunction.setFileName(m_header);
            // build parameter list
            inMethod = true;
            visit(node->parameter_declaration_clause);
            inMethod = false;
            QString name = currentFunction.toString();
            if (!functions.contains(name)) {
                functions[name] = currentFunction;
            }
        }
        return;
    }
    
    // field
    if (!inMethod && !klass.isEmpty() && inClass) {
        Field field = Field(klass.top(), declName, currentTypeRef, access.top());
        if (isStatic) field.setFlag(Field::Static);
        klass.top()->appendField(field);
        return;
    } else if (!inMethod && !inClass) {
        // global variable
        if (!globals.contains(declName)) {
            GlobalVar var = GlobalVar(declName, nspace.join("::"), currentTypeRef);
            var.setFileName(m_header);
            globals[var.name()] = var;
        }
        return;
    }
}

void GeneratorVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
{
    tc->run(node);
    createType = true;
    DefaultVisitor::visitElaboratedTypeSpecifier(node);
}

void GeneratorVisitor::visitEnumSpecifier(EnumSpecifierAST* node)
{
    nc->run(node->name);
    Class* parent = klass.isEmpty() ? 0 : klass.top();
    currentEnum = Enum(nc->name(), nspace.join("::"), parent);
    Access a = (access.isEmpty() ? Access_public : access.top());
    currentEnum.setAccess(a);
    currentEnum.setFileName(m_header);
    QHash<QString, Enum>::iterator it = enums.insert(currentEnum.toString(), currentEnum);
    currentEnumRef = &it.value();
    visitNodes(this, node->enumerators);
    if (parent)
        parent->appendChild(currentEnumRef);
}

void GeneratorVisitor::visitEnumerator(EnumeratorAST* node)
{
    currentEnumRef->appendMember(EnumMember(currentEnumRef, token(node->id).symbolString(), QString()));
//     DefaultVisitor::visitEnumerator(node);
}

void GeneratorVisitor::visitFunctionDefinition(FunctionDefinitionAST* node)
{
    visit(node->type_specifier);
    if (node->function_specifiers) {
        const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
        do {
            if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
                // found virtual token
                isVirtual = true;
            } else if (it->element && m_session->token_stream->kind(it->element) == Token_explicit) {
                isExplicit = true;
            }
            it = it->next;
        } while (end != it);
    }
    if (node->storage_specifiers) {
        const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
        do {
            if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
                isStatic = true;
            } else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
                // we're not interested in who's the friend of whom ;)
                return;
            }
            it = it->next;
        } while (end != it);
    }



( run in 0.765 second using v1.01-cache-2.11-cpan-13bb782fe5a )