Exemple #1
0
QList<const TopLevelDataInformation*> OsdParser::parseStructures()
{
    QFileInfo fileInfo(mDir, mFile);
    QDomElement rootElem = mDocument.firstChildElement(QLatin1String("data"));

    parseEnums();

    QList<const TopLevelDataInformation*> structures;
    QDomNodeList list = rootElem.childNodes();
    for (uint i = 0; i < list.length(); ++i)
    {
        const QDomNode& n = list.at(i);
        QDomElement elem = n.toElement(); // try to convert the node to an element.
        if (elem.isNull())
            continue;

        //e is element
        //kDebug() << "element tag: " << elem.tagName();
        QString tag = elem.tagName();
        DataInformation* data = parseNode(elem, 0);
        if (data)
        {
            TopLevelDataInformation* topData = new TopLevelDataInformation(data, fileInfo, mEngine, false);
            structures.append(topData);
        }
        else
        {
            kDebug() << "data == NULL -> could not parse node " << elem.tagName();
            delete data;
        }
    }
    mFullyParsed = true; //however if this method is called again the result will not be cached
    return structures;
}
Exemple #2
0
AbstractEnumDataInformation* OsdParser::enumFromXML(const QDomElement& xmlElem, bool isFlags)
{
    if (!mEnumsParsed) //not always needed
        parseEnums();

    QString name = xmlElem.attribute(QLatin1String("name"), i18n("<invalid name>"));
    QString typeStr = xmlElem.attribute(QLatin1String("type"), QString());
    if (typeStr.isEmpty())
    {
        kWarning() << "no type attribute defined";
        return NULL;
    }
    QString enumName = xmlElem.attribute(QLatin1String("enum"), QString());
    if (enumName.isEmpty())
    {
        kWarning() << "no enum attribute defined";
        return NULL;
    }
    EnumDefinition::Ptr def = findEnum(enumName);
    if (!def)
    {
        kWarning() << "no enum with name " << enumName << "found.";
        return NULL;
    }
    PrimitiveDataInformation* prim = PrimitiveFactory::newInstance(name, typeStr);
    if (!prim)
    {
        kWarning() << "primitive type is null!!";
        return NULL;
    }

    if (isFlags)
       return new FlagDataInformation(name, prim, def);
    else
        return new EnumDataInformation(name, prim, def);
}
Exemple #3
0
ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema)
{
    clang::Preprocessor &PP = Sema.getPreprocessor();
    ClassDef Def;
    Def.Record = RD;

    for (auto it = RD->decls_begin(); it != RD->decls_end(); ++it) {
        if (clang::StaticAssertDecl *S = llvm::dyn_cast<clang::StaticAssertDecl>(*it) ) {
            if (auto *E = llvm::dyn_cast<clang::UnaryExprOrTypeTraitExpr>(S->getAssertExpr()))
                if (clang::ParenExpr *PE = llvm::dyn_cast<clang::ParenExpr>(E->getArgumentExpr()))
            {
                llvm::StringRef key = S->getMessage()->getString();
                if (key == "qt_property") {
                    clang::StringLiteral *Val = llvm::dyn_cast<clang::StringLiteral>(PE->getSubExpr());
                    if (Val) {
                        PropertyParser Parser(Val->getString(),
    //                                          Val->getStrTokenLoc(0),
                                            Val->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()),
                                            Sema, Def.Record);
                        Def.Properties.push_back(Parser.parseProperty());
                        Def.addExtra(Parser.Extra);
                    } else {
                        PP.getDiagnostics().Report(S->getLocation(),
                                                   PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                                   "Invalid Q_PROPERTY annotation"));
                    }
                } else if (key == "qt_private_property") {
                    clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr;
                    std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_PRIVATE_PROPERTY",
                                                           "Invalid Q_PRIVATE_PROPERTY annotation");

                    if (Val1 && Val2) {
                        PropertyParser Parser(Val2->getString(),
                                              Val2->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()),
                                              Sema, Def.Record);
                        PropertyDef P = Parser.parseProperty(true);
                        P.inPrivateClass = Val1->getString();
                        Def.Properties.push_back(std::move(P));
                        Def.addExtra(Parser.Extra);
                    }
                } else if (key == "qt_private_slot") {
                    clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr;
                    std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_PRIVATE_SLOT",
                                                           "Invalid Q_PRIVATE_SLOT annotation");
                    if (Val1 && Val2) {
                        PropertyParser Parser(Val2->getString(),
                                              Val2->getLocationOfByte(0, PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo()),
                                              Sema, Def.Record);
                        PrivateSlotDef P = Parser.parsePrivateSlot();
                        P.InPrivateClass = Val1->getString();
                        if (!P.Name.empty()) {
                            Def.PrivateSlotCount += P.NumDefault + 1;
                            Def.PrivateSlots.push_back(std::move(P));
                        }
                    }
                } else if (key == "qt_enums")  {
                    parseEnums(Def, false, PE->getSubExpr(), Sema);
                } else if (key == "qt_flags")  {
                    parseEnums(Def, true, PE->getSubExpr(), Sema);
                } else if (key == "qt_qobject") {
                    Def.HasQObject = true;
                } else if (key == "qt_fake") {
                    Def.HasQGadget = false;
                } else if (key == "qt_qgadget") {
                    Def.HasQGadget = true;
                } else if (key == "qt_classinfo") {
                    clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr;
                    std::tie(Val1, Val2) = ExtractLiterals(PE, PP, "Q_CLASSINFO",
                                                           "Expected string literal in Q_CLASSINFO");

                    if (Val1 && Val2) {
                        Def.ClassInfo.emplace_back(Val1->getString(), Val2->getString());
                    }
                } else if (key == "qt_interfaces") {
                    parseInterfaces(Def, PE->getSubExpr(), Sema);
                } else if (key == "qt_plugin_metadata") {
                    parsePluginMetaData(Def, PE->getSubExpr(), Sema);
                    HasPlugin = true;
                }
            }
        } else if (clang::CXXMethodDecl *M = llvm::dyn_cast<clang::CXXMethodDecl>(*it)) {
            for (auto attr_it = M->specific_attr_begin<clang::AnnotateAttr>();
                attr_it != M->specific_attr_end<clang::AnnotateAttr>();
                ++attr_it) {

                const clang::AnnotateAttr *A = *attr_it;
                if (A->getAnnotation() == "qt_signal") {
                        Def.Signals.push_back(M);
                } else if (A->getAnnotation() == "qt_slot") {
                        Def.Slots.push_back(M);
                } else if (A->getAnnotation() == "qt_invokable" || A->getAnnotation() == "qt_scriptable" ) {
                    if (auto *C = llvm::dyn_cast<clang::CXXConstructorDecl>(M)) {
                            Def.Constructors.push_back(C);
                    } else {
                            Def.Methods.push_back(M);
                    }
                } else if (A->getAnnotation().startswith("qt_revision:")) {
                    Def.RevisionMethodCount++;
                }
            }
        }
    }

    //Check notify Signals
    for (PropertyDef &P: Def.Properties) {
        if (!P.notify.Str.empty()) {
            int Idx = 0;
            for (clang::CXXMethodDecl *MD : Def.Signals) {
                if (MD->getName() == P.notify.Str) {
                    P.notify.notifyId = Idx;
                    P.notify.MD = MD;
                    break;
                }
                Idx += 1 + MD->getNumParams() - MD->getMinRequiredArguments();
            }
            if (P.notify.notifyId < 0 ) {
                PP.getDiagnostics().Report(P.notify.Loc,
                        PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                        "NOTIFY signal '%0' of property '%1' does not exist in class %2"))
                    << P.notify.Str << P.name << Def.Record;
            } else {
                Def.NotifyCount++;
            }
        }

        if (P.revision > 0)
            Def.RevisionPropertyCount++;
    }
    return Def;
}