示例#1
0
bool CSeqParser::parseClassDeclare( char* &start, char *end, wd::CSeqLog &log, std::list< std::pair< char*, std::string > > &error_info )
{
    for( char chr = *start; chr != '\0'; chr = *start )
    {
        switch ( chr )
        {
            //类注释
        case '/':
            log.classDescript = takeNextRemake( start, end );
            break;

            //取得下一个可解释字符串
        case '\r':
        case '\n':
        case ' ':
        case '\t':
            gotoNextChar( start, end );
            break;

        case '#':
            gotoNextLine( start, end );
            break;

            //不应该出现;号
        case ';':
            ++start;
            pushErrorInfo( error_info, start, "不应该出现的符号 ';'" );
            break;
        case ':':
            log.classParent = takeNextWord( ++start, end );
            if ( log.classParent.empty() )
                pushErrorInfo( error_info, start, "类继承缺少父类名称" );
            break;
        case '{':
            parseClassInfo( ++start, end, log, error_info );
            return true;
        default:
            if ( !checkChar( chr ) )
            {
                pushErrorInfo( error_info, start, "遇到不可解释的符号, 期望是一个字母、数字和半角下划线" );
                return false;
            }

            log.className = takeNextWord( start, end );
            if ( log.className.empty() )
            {
                pushErrorInfo( error_info, start, "声明类时缺失类名声明" );
                return false;
            }
            break;
        }
    }

    pushErrorInfo( error_info, start, ( "找不到类 [" + log.className + "] 的 '{' , 类定义失败" ).c_str() );
    return false;
}
示例#2
0
void MetaInfoPrivate::parseNonQmlClassRecursively(const QMetaObject *qMetaObject)
{
    Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject");

    QString typeName;
    int majorVersion = -1;
    int minorVersion = -1;
    typeInfo(qMetaObject, &typeName, &majorVersion, &minorVersion);

    if (typeName.isEmpty()) {
        qWarning() << "Meta type system: Registered class has no name.";
        return;
    }

    NodeMetaInfo existingInfo = m_q->nodeMetaInfo(typeName, majorVersion, minorVersion);
    if (existingInfo.isValid()
        && existingInfo.majorVersion() == majorVersion
        && existingInfo.minorVersion() == minorVersion) {
        return;
    }

    NodeMetaInfo nodeMetaInfo(*m_q);
    nodeMetaInfo.setType(typeName, majorVersion, minorVersion);
    parseProperties(nodeMetaInfo, qMetaObject);
    parseClassInfo(nodeMetaInfo, qMetaObject);

    QString superTypeName;
    int superTypeMajorVersion = -1;
    int superTypeMinorVersion = -1;

    if (qMetaObject->superClass()) {
        typeInfo(qMetaObject->superClass(), &superTypeName, &superTypeMajorVersion, &superTypeMinorVersion);
        nodeMetaInfo.setSuperClass(superTypeName, superTypeMajorVersion, superTypeMinorVersion);
    }
    if (debug)
        qDebug() << "adding non qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion()
                 << ", parent type" << superTypeName << superTypeMajorVersion << superTypeMinorVersion;

    m_q->addNodeInfo(nodeMetaInfo);

    if (const QMetaObject *superClass = qMetaObject->superClass())
        parseNonQmlClassRecursively(superClass);
}
示例#3
0
void Moc::parse()
{
    QList<NamespaceDef> namespaceList;
    bool templateClass = false;
    while (hasNext()) {
        Token t = next();
        switch (t) {
            case NAMESPACE: {
                int rewind = index;
                if (test(IDENTIFIER)) {
                    if (test(EQ)) {
                        // namespace Foo = Bar::Baz;
                        until(SEMIC);
                    } else if (!test(SEMIC)) {
                        NamespaceDef def;
                        def.name = lexem();
                        next(LBRACE);
                        def.begin = index - 1;
                        until(RBRACE);
                        def.end = index;
                        index = def.begin + 1;
                        namespaceList += def;
                        index = rewind;
                    }
                }
                break;
            }
            case SEMIC:
            case RBRACE:
                templateClass = false;
                break;
            case TEMPLATE:
                templateClass = true;
                break;
            case MOC_INCLUDE_BEGIN:
                currentFilenames.push(symbol().unquotedLexem());
                break;
            case MOC_INCLUDE_END:
                currentFilenames.pop();
                break;
            case Q_DECLARE_INTERFACE_TOKEN:
                parseDeclareInterface();
                break;
            case Q_DECLARE_METATYPE_TOKEN:
                parseDeclareMetatype();
                break;
            case USING:
                if (test(NAMESPACE)) {
                    while (test(SCOPE) || test(IDENTIFIER))
                        ;
                    next(SEMIC);
                }
                break;
            case CLASS:
            case STRUCT: {
                if (currentFilenames.size() <= 1)
                    break;

                ClassDef def;
                if (!parseClassHead(&def))
                    continue;

                while (inClass(&def) && hasNext()) {
                    if (next() == Q_OBJECT_TOKEN) {
                        def.hasQObject = true;
                        break;
                    }
                }

                if (!def.hasQObject)
                    continue;

                for (int i = namespaceList.size() - 1; i >= 0; --i)
                    if (inNamespace(&namespaceList.at(i)))
                        def.qualified.prepend(namespaceList.at(i).name + "::");

                knownQObjectClasses.insert(def.classname);
                knownQObjectClasses.insert(def.qualified);

                continue; }
            default: break;
        }
        if ((t != CLASS && t != STRUCT)|| currentFilenames.size() > 1)
            continue;
        ClassDef def;
        if (parseClassHead(&def)) {
            FunctionDef::Access access = FunctionDef::Private;
            for (int i = namespaceList.size() - 1; i >= 0; --i)
                if (inNamespace(&namespaceList.at(i)))
                    def.qualified.prepend(namespaceList.at(i).name + "::");
            while (inClass(&def) && hasNext()) {
                switch ((t = next())) {
                case PRIVATE:
                    access = FunctionDef::Private;
                    if (test(Q_SIGNALS_TOKEN))
                        error("Signals cannot have access specifier");
                    break;
                case PROTECTED:
                    access = FunctionDef::Protected;
                    if (test(Q_SIGNALS_TOKEN))
                        error("Signals cannot have access specifier");
                    break;
                case PUBLIC:
                    access = FunctionDef::Public;
                    if (test(Q_SIGNALS_TOKEN))
                        error("Signals cannot have access specifier");
                    break;
                case CLASS: {
                    ClassDef nestedDef;
                    if (parseClassHead(&nestedDef)) {
                        while (inClass(&nestedDef) && inClass(&def)) {
                            t = next();
                            if (t >= Q_META_TOKEN_BEGIN && t < Q_META_TOKEN_END)
                                error("Meta object features not supported for nested classes");
                        }
                    }
                } break;
                case Q_SIGNALS_TOKEN:
                    parseSignals(&def);
                    break;
                case Q_SLOTS_TOKEN:
                    switch (lookup(-1)) {
                    case PUBLIC:
                    case PROTECTED:
                    case PRIVATE:
                        parseSlots(&def, access);
                        break;
                    default:
                        error("Missing access specifier for slots");
                    }
                    break;
                case Q_OBJECT_TOKEN:
                    def.hasQObject = true;
                    if (templateClass)
                        error("Template classes not supported by Q_OBJECT");
                    if (def.classname != "Qt" && def.classname != "QObject" && def.superclassList.isEmpty())
                        error("Class contains Q_OBJECT macro but does not inherit from QObject");
                    break;
                case Q_GADGET_TOKEN:
                    def.hasQGadget = true;
                    if (templateClass)
                        error("Template classes not supported by Q_GADGET");
                    break;
                case Q_PROPERTY_TOKEN:
                    parseProperty(&def);
                    break;
                case Q_ENUMS_TOKEN:
                    parseEnumOrFlag(&def, false);
                    break;
                case Q_FLAGS_TOKEN:
                    parseEnumOrFlag(&def, true);
                    break;
                case Q_DECLARE_FLAGS_TOKEN:
                    parseFlag(&def);
                    break;
                case Q_CLASSINFO_TOKEN:
                    parseClassInfo(&def);
                    break;
                case Q_INTERFACES_TOKEN:
                    parseInterfaces(&def);
                    break;
                case Q_PRIVATE_SLOT_TOKEN:
                    parseSlotInPrivate(&def, access);
                    break;
                case Q_PRIVATE_PROPERTY_TOKEN:
                    parsePrivateProperty(&def);
                    break;
                case ENUM: {
                    EnumDef enumDef;
                    if (parseEnum(&enumDef))
                        def.enumList += enumDef;
                } break;
                default:
                    FunctionDef funcDef;
                    funcDef.access = access;
                    int rewind = index;
                    if (parseMaybeFunction(&def, &funcDef)) {
                        if (funcDef.isConstructor) {
                            if ((access == FunctionDef::Public) && funcDef.isInvokable) {
                                def.constructorList += funcDef;
                                while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
                                    funcDef.wasCloned = true;
                                    funcDef.arguments.removeLast();
                                    def.constructorList += funcDef;
                                }
                            }
                        } else if (funcDef.isDestructor) {
                            // don't care about destructors
                        } else {
                            if (access == FunctionDef::Public)
                                def.publicList += funcDef;
                            if (funcDef.isSlot) {
                                def.slotList += funcDef;
                                while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
                                    funcDef.wasCloned = true;
                                    funcDef.arguments.removeLast();
                                    def.slotList += funcDef;
                                }
                            } else if (funcDef.isSignal) {
                                def.signalList += funcDef;
                                while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
                                    funcDef.wasCloned = true;
                                    funcDef.arguments.removeLast();
                                    def.signalList += funcDef;
                                }
                            } else if (funcDef.isInvokable) {
                                def.methodList += funcDef;
                                while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
                                    funcDef.wasCloned = true;
                                    funcDef.arguments.removeLast();
                                    def.methodList += funcDef;
                                }
                            }
                        }
                    } else {
                        index = rewind;
                    }
                }
            }

            next(RBRACE);

            if (!def.hasQObject && !def.hasQGadget && def.signalList.isEmpty() && def.slotList.isEmpty()
                && def.propertyList.isEmpty() && def.enumDeclarations.isEmpty())
                continue; // no meta object code required


            if (!def.hasQObject && !def.hasQGadget)
                error("Class declarations lacks Q_OBJECT macro.");

            checkSuperClasses(&def);
            checkProperties(&def);

            classList += def;
            knownQObjectClasses.insert(def.classname);
            knownQObjectClasses.insert(def.qualified);
        }
    }
}