File indexing completed on 2024-04-28 03:40:43

0001 /*************************************************************************************
0002  *  Copyright (C) 2011 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program is distributed in the hope that it will be useful,                  *
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "importqobjectmetatype.h"
0020 #include "analyzer.h"
0021 #include <QMetaProperty>
0022 #include "analitzautils.h"
0023 #include "value.h"
0024 
0025 using namespace Analitza;
0026 
0027 ExpressionType toExpressionType(QVariant::Type t, const QString& type_name)
0028 {
0029     switch(t)
0030     {
0031         case QVariant::Int:
0032         case QVariant::Double:
0033             return ExpressionType(ExpressionType::Value);
0034         case QVariant::String:
0035             return ExpressionType(ExpressionType::List, ExpressionType(ExpressionType::Char));
0036         default:
0037             return ExpressionType(type_name);
0038     }
0039 }
0040 
0041 class QObjectGet : public Analitza::FunctionDefinition
0042 {
0043     public:
0044         QObjectGet(const QByteArray& name) : m_name(name) {}
0045     
0046         virtual Expression operator()(const QList< Expression >& args) override
0047         {
0048             QObject* o=args.first().customObjectValue().value<QObject*>();
0049             QVariant v=o->property(m_name);
0050             
0051             return AnalitzaUtils::variantToExpression(v);
0052         }
0053         
0054         ExpressionType type(const QByteArray& name, const QMetaProperty& prop) const
0055         {
0056             ExpressionType typeGet(ExpressionType::Lambda);
0057             typeGet.addParameter(ExpressionType(name))
0058                 .addParameter(toExpressionType(prop.type(), prop.typeName()));
0059             
0060             return typeGet;
0061         }
0062         
0063     private:
0064         QByteArray m_name;
0065 };
0066 
0067 class QObjectSet : public Analitza::FunctionDefinition
0068 {
0069     public:
0070         QObjectSet(const QByteArray& name) : m_name(name) {}
0071     
0072         virtual Expression operator()(const QList< Expression >& args) override
0073         {
0074             QObject* o=args.first().customObjectValue().value<QObject*>();
0075             QVariant value=AnalitzaUtils::expressionToVariant(args.last());
0076             
0077             return Expression(Cn(o->setProperty(m_name, value)));
0078         }
0079         
0080         ExpressionType type(const QByteArray& name, const QMetaProperty& prop) const
0081         {
0082             ExpressionType typeSet(ExpressionType::Lambda);
0083             typeSet.addParameter(ExpressionType(name))
0084                 .addParameter(toExpressionType(prop.type(), prop.typeName()))
0085                 .addParameter(ExpressionType(ExpressionType::Bool));
0086             
0087             return typeSet;
0088         }
0089         
0090     private:
0091         QByteArray m_name;
0092 };
0093 
0094 class QObjectCastToParent : public Analitza::FunctionDefinition
0095 {
0096     public:
0097         QObjectCastToParent(const QByteArray& name, const QByteArray& nameParent)
0098             : m_name(name), m_nameParent(nameParent) {}
0099         
0100         virtual Expression operator()(const QList< Expression >& args) override
0101         {
0102             QObject* o=args.first().customObjectValue().value<QObject*>();
0103             return Expression::constructCustomObject(QVariant::fromValue<QObject*>(o), nullptr);
0104         }
0105         
0106         ExpressionType type() const
0107         {
0108             ExpressionType typeCast(ExpressionType::Lambda);
0109             typeCast.addParameter(ExpressionType(m_name))
0110                 .addParameter(ExpressionType(m_nameParent));
0111             
0112             return typeCast;
0113         }
0114     private:
0115         QByteArray m_name;
0116         QByteArray m_nameParent;
0117 };
0118 
0119 ImportQMetaObject::ImportQMetaObject(Analitza::Analyzer* a)
0120     : m_a(a)
0121 {}
0122 
0123 void ImportQMetaObject::import(const QMetaObject& t)
0124 {
0125     Analitza::BuiltinMethods* b=m_a->builtinMethods();
0126     QByteArray classname(t.className());
0127     classname.replace("::", "_");
0128     
0129     for(int p=0; p<t.propertyCount(); p++) {
0130         QMetaProperty prop=t.property(p);
0131         QByteArray name(prop.name());
0132         
0133         if(prop.isReadable()) {
0134             QObjectGet* getter=new QObjectGet(name);
0135             b->insertFunction(QString(classname+'_'+name), getter->type(classname, prop), getter);
0136         }
0137         
0138         if(prop.isWritable()) {
0139             QObjectSet* setter=new QObjectSet(name);
0140             b->insertFunction(QString(classname+"_set_"+name), setter->type(classname, prop), setter);
0141         }
0142     }
0143     
0144     if(t.superClass()) {
0145         QObjectCastToParent *cast = new QObjectCastToParent(t.className(), t.superClass()->className());
0146         b->insertFunction(classname+QStringLiteral("_toParent"), cast->type(), cast);
0147     }
0148 }
0149