⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moc.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    while (test(CONST) || test(VOLATILE) || test(SIGNED) || test(UNSIGNED)           || test(STAR) || test(AND)) {        type.name += ' ';        type.name += lexem();        if (lookup(0) == AND)            type.referenceType = Type::Reference;        else if (lookup(0) == STAR)            type.referenceType = Type::Pointer;    }    // transform stupid things like 'const void' or 'void const' into 'void'    if (isVoid && type.referenceType == Type::NoReference) {        type.name = "void";    }    return type;}bool Moc::parseEnum(EnumDef *def){    if (!test(IDENTIFIER))        return false; // anonymous enum    def->name = lexem();    if (!test(LBRACE))        return false;    do {        if (lookup() == RBRACE) // accept trailing comma            break;        next(IDENTIFIER);        def->values += lexem();    } while (test(EQ) ? until(COMMA) : test(COMMA));    next(RBRACE);    return true;}void Moc::parseFunctionArguments(FunctionDef *def){    Q_UNUSED(def);    while (hasNext()) {        ArgumentDef  arg;        arg.type = parseType();        if (arg.type.name == "void")            break;        if (test(IDENTIFIER))            arg.name = lexem();        while (test(LBRACK)) {            arg.rightType += lexemUntil(RBRACK);        }        if (test(CONST) || test(VOLATILE)) {            arg.rightType += ' ';            arg.rightType += lexem();        }        arg.normalizedType = normalizeType(arg.type.name + ' ' + arg.rightType);        arg.typeNameForCast = normalizeType(noRef(arg.type.name) + "(*)" + arg.rightType);        if (test(EQ))            arg.isDefault = true;        def->arguments += arg;        if (!until(COMMA))            break;    }}// returns false if the function should be ignoredbool Moc::parseFunction(FunctionDef *def, bool inMacro){    def->isVirtual = false;    while (test(INLINE) || test(STATIC) || test(VIRTUAL)) {        if (lookup() == VIRTUAL)            def->isVirtual = true;    }    bool templateFunction = (lookup() == TEMPLATE);    def->type = parseType();    if (def->type.name.isEmpty()) {        if (templateFunction)            error("Template function as signal or slot");        else            error();    }    bool scopedFunctionName = false;    if (test(LPAREN)) {        def->name = def->type.name;        scopedFunctionName = def->type.isScoped;        def->type = Type("int");    } else {        Type tempType = parseType();;        while (!tempType.name.isEmpty() && lookup() != LPAREN) {            if (def->type.name == "QT_MOC_COMPAT" || def->type.name == "QT3_SUPPORT")                def->isCompat = true;            else if (def->type.name == "Q_INVOKABLE")                def->isInvokable = true;            else if (def->type.name == "Q_SCRIPTABLE")                def->isInvokable = def->isScriptable = true;            else if (def->type.name == "Q_SIGNAL")                error();            else if (def->type.name == "Q_SLOT")                error();            else {                if (!def->tag.isEmpty())                    def->tag += ' ';                def->tag += def->type.name;            }            def->type = tempType;            tempType = parseType();        }        next(LPAREN, "Not a signal or slot declaration");        def->name = tempType.name;        scopedFunctionName = tempType.isScoped;    }        // we don't support references as return types, it's too dangerous    if (def->type.referenceType == Type::Reference)        def->type = Type("void");    def->normalizedType = normalizeType(def->type.name);    if (!test(RPAREN)) {        parseFunctionArguments(def);        next(RPAREN);    }    // support optional macros with compiler specific options    while (test(IDENTIFIER))        ;    def->isConst = test(CONST);    while (test(IDENTIFIER))        ;    if (inMacro) {        next(RPAREN);    } else {        if (test(SEMIC))            ;        else if ((def->inlineCode = test(LBRACE)))            until(RBRACE);        else if (test(EQ) || test(THROW))            until(SEMIC);        else            error();    }    if (scopedFunctionName) {        QByteArray msg("Function declaration ");        msg += def->name;        msg += " contains extra qualification. Ignoring as signal or slot.";        warning(msg.constData());        return false;    }    return true;}// like parseFunction, but never aborts with an errorbool Moc::parseMaybeFunction(FunctionDef *def){    def->type = parseType();    if (def->type.name.isEmpty())        return false;    bool scopedFunctionName = false;        if (test(LPAREN)) {        def->name = def->type.name;        scopedFunctionName = def->type.isScoped;        def->type = Type("int");    } else {        Type tempType = parseType();;        while (!tempType.name.isEmpty() && lookup() != LPAREN) {            if (def->type.name == "QT_MOC_COMPAT" || def->type.name == "QT3_SUPPORT")                def->isCompat = true;            else if (def->type.name == "Q_INVOKABLE")                def->isInvokable = true;            else if (def->type.name == "Q_SCRIPTABLE")                def->isInvokable = def->isScriptable = true;            else if (def->type.name == "Q_SIGNAL")                def->isSignal = true;            else if (def->type.name == "Q_SLOT")                def->isSlot = true;            else {                if (!def->tag.isEmpty())                    def->tag += ' ';                def->tag += def->type.name;            }            def->type = tempType;            tempType = parseType();        }        if (!test(LPAREN))            return false;        def->name = tempType.name;        scopedFunctionName = tempType.isScoped;    }    // we don't support references as return types, it's too dangerous    if (def->type.referenceType == Type::Reference)        def->type = Type("void");    def->normalizedType = normalizeType(def->type.name);    if (!test(RPAREN)) {        parseFunctionArguments(def);        if (!test(RPAREN))            return false;    }    def->isConst = test(CONST);    if (scopedFunctionName        && (def->isSignal || def->isSlot || def->isInvokable)) {        QByteArray msg("parsemaybe: Function declaration ");        msg += def->name;        msg += " contains extra qualification. Ignoring as signal or slot.";        warning(msg.constData());        return false;    }    return true;}void Moc::parse(){    currentFilenames.push(filename);    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:                next(STRING_LITERAL);                currentFilenames.push(symbol().unquotedLexem());                break;            case MOC_INCLUDE_END:                currentFilenames.pop();                break;            case Q_DECLARE_INTERFACE_TOKEN:                parseDeclareInterface();                break;            case USING:                if (test(NAMESPACE)) {                    while (test(SCOPE) || test(IDENTIFIER))                        ;                    next(SEMIC);                }                break;            default: break;        }        if (t != CLASS || currentFilenames.size() > 1)            continue;        ClassDef def;        FunctionDef::Access access = FunctionDef::Private;        if (parseClassHead(&def)) {            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(SIGNALS))                        error("Signals cannot have access specifier");                    break;                case PROTECTED:                    access = FunctionDef::Protected;                    if (test(SIGNALS))                        error("Signals cannot have access specifier");                    break;                case PUBLIC:                    access = FunctionDef::Public;                    if (test(SIGNALS))                        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 SIGNALS:                    parseSignals(&def);                    break;                case SLOTS:                    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 ENUM: {                    EnumDef enumDef;                    if (parseEnum(&enumDef))                        def.enumList += enumDef;                } break;                default:                    FunctionDef funcDef;                    funcDef.access = access;                    int rewind = index;                    if (parseMaybeFunction(&funcDef)) {                        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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -