Translate data types to Python data types for Python generation

This commit is contained in:
Gaute Lindkvist 2020-03-03 13:06:07 +01:00
parent b2f55a3101
commit 554f9a1758
13 changed files with 175 additions and 35 deletions

View File

@ -99,7 +99,10 @@ void RicfFieldReader<QString>::readFieldData( QString& fieldValue,
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicfFieldWriter<QString>::writeFieldData( const QString& fieldValue, QTextStream& outputStream, bool quoteStrings ) void RicfFieldWriter<QString>::writeFieldData( const QString& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{ {
outputStream << "\""; outputStream << "\"";
for ( int i = 0; i < fieldValue.size(); ++i ) for ( int i = 0; i < fieldValue.size(); ++i )
@ -155,7 +158,10 @@ void RicfFieldReader<bool>::readFieldData( bool& fieldValue,
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicfFieldWriter<bool>::writeFieldData( const bool& fieldValue, QTextStream& outputStream, bool quoteStrings ) void RicfFieldWriter<bool>::writeFieldData( const bool& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{ {
// Lower-case true/false is used in the documentation. // Lower-case true/false is used in the documentation.
outputStream << ( fieldValue ? "true" : "false" ); outputStream << ( fieldValue ? "true" : "false" );
@ -182,7 +188,10 @@ void RicfFieldReader<cvf::Color3f>::readFieldData( cvf::Color3f& fieldValue,
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RicfFieldWriter<cvf::Color3f>::writeFieldData( const cvf::Color3f& fieldValue, QTextStream& outputStream, bool quoteStrings ) void RicfFieldWriter<cvf::Color3f>::writeFieldData( const cvf::Color3f& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{ {
QColor qColor = RiaColorTools::toQColor( fieldValue ); QColor qColor = RiaColorTools::toQColor( fieldValue );
QString fieldStringValue = qColor.name(); QString fieldStringValue = qColor.name();

View File

@ -51,7 +51,10 @@ struct RicfFieldReader
template <typename DataType> template <typename DataType>
struct RicfFieldWriter struct RicfFieldWriter
{ {
static void writeFieldData( const DataType& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) static void writeFieldData( const DataType& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{ {
outputStream << fieldValue; outputStream << fieldValue;
} }
@ -69,7 +72,10 @@ struct RicfFieldReader<QString>
template <> template <>
struct RicfFieldWriter<QString> struct RicfFieldWriter<QString>
{ {
static void writeFieldData( const QString& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); static void writeFieldData( const QString& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
}; };
template <> template <>
@ -84,7 +90,10 @@ struct RicfFieldReader<bool>
template <> template <>
struct RicfFieldWriter<bool> struct RicfFieldWriter<bool>
{ {
static void writeFieldData( const bool& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); static void writeFieldData( const bool& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
}; };
template <> template <>
@ -99,7 +108,10 @@ struct RicfFieldReader<cvf::Color3f>
template <> template <>
struct RicfFieldWriter<cvf::Color3f> struct RicfFieldWriter<cvf::Color3f>
{ {
static void writeFieldData( const cvf::Color3f& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); static void writeFieldData( const cvf::Color3f& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
}; };
template <typename T> template <typename T>
@ -141,10 +153,20 @@ struct RicfFieldReader<caf::AppEnum<T>>
template <typename T> template <typename T>
struct RicfFieldWriter<caf::AppEnum<T>> struct RicfFieldWriter<caf::AppEnum<T>>
{ {
static void writeFieldData( const caf::AppEnum<T>& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) static void writeFieldData( const caf::AppEnum<T>& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
if ( quoteNonBuiltins )
{
outputStream << "\"" << fieldValue << "\"";
}
else
{ {
outputStream << fieldValue; outputStream << fieldValue;
} }
}
}; };
template <typename T> template <typename T>
@ -191,12 +213,15 @@ struct RicfFieldReader<std::vector<T>>
template <typename T> template <typename T>
struct RicfFieldWriter<std::vector<T>> struct RicfFieldWriter<std::vector<T>>
{ {
static void writeFieldData( const std::vector<T>& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) static void writeFieldData( const std::vector<T>& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{ {
outputStream << "["; outputStream << "[";
for ( size_t i = 0; i < fieldValue.size(); ++i ) for ( size_t i = 0; i < fieldValue.size(); ++i )
{ {
RicfFieldWriter<T>::writeFieldData( fieldValue[i], outputStream ); RicfFieldWriter<T>::writeFieldData( fieldValue[i], outputStream, quoteNonBuiltins );
if ( i < fieldValue.size() - 1 ) if ( i < fieldValue.size() - 1 )
{ {
outputStream << ", "; outputStream << ", ";
@ -240,9 +265,12 @@ public:
} }
} }
void writeFieldData( QTextStream& outputStream, bool quoteStrings = true ) const override void writeFieldData( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const override
{ {
RicfFieldWriter<typename FieldType::FieldDataType>::writeFieldData( m_field->value(), outputStream, quoteStrings ); RicfFieldWriter<typename FieldType::FieldDataType>::writeFieldData( m_field->value(),
outputStream,
quoteStrings,
quoteNonBuiltins );
} }
private: private:

View File

@ -46,7 +46,6 @@ public:
caf::PdmObjectFactory* objectFactory, caf::PdmObjectFactory* objectFactory,
RicfMessages* errorMessageContainer, RicfMessages* errorMessageContainer,
bool stringsAreQuoted = true ) = 0; bool stringsAreQuoted = true ) = 0;
virtual void writeFieldData( QTextStream& outputStream, bool quoteStrings = true ) const = 0;
private: private:
caf::PdmFieldHandle* m_owner; caf::PdmFieldHandle* m_owner;

View File

@ -38,6 +38,8 @@
#include <QString> #include <QString>
#include "cafPdmFieldCapability.h" #include "cafPdmFieldCapability.h"
class QTextStream;
namespace caf { namespace caf {
class PdmFieldHandle; class PdmFieldHandle;
@ -53,6 +55,7 @@ public:
bool isIOWriteable() const; bool isIOWriteable() const;
void setIOWriteable(bool writeable); void setIOWriteable(bool writeable);
virtual void writeFieldData(QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false) const = 0;
private: private:
caf::PdmFieldHandle* m_owner; caf::PdmFieldHandle* m_owner;
QString m_scriptFieldName; QString m_scriptFieldName;

View File

@ -40,6 +40,7 @@
#include "cafPdmObjectFactory.h" #include "cafPdmObjectFactory.h"
#include "cafPdmObjectScriptabilityRegister.h" #include "cafPdmObjectScriptabilityRegister.h"
#include "cafPdmProxyValueField.h" #include "cafPdmProxyValueField.h"
#include "cafPdmXmlFieldHandle.h"
#include <QRegularExpression> #include <QRegularExpression>
#include <QTextStream> #include <QTextStream>
@ -136,7 +137,9 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
} }
QVariant valueVariant = pdmValueField->toQVariant(); QVariant valueVariant = pdmValueField->toQVariant();
QString dataTypeString = valueVariant.typeName();
bool isList, isBuiltinType;
QString dataType = PdmPythonGenerator::dataTypeString(pdmValueField, &isList, &isBuiltinType);
if (shouldBeMethod) if (shouldBeMethod)
{ {
@ -145,7 +148,7 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
QString fullComment = QString fullComment =
QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"") QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"")
.arg(comment) .arg(comment)
.arg(dataTypeString); .arg(dataType);
QString fieldCode = QString(" def %1(self):\n%2\n return " QString fieldCode = QString(" def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n") "self._call_get_method(\"%3\")\n")
@ -156,10 +159,10 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
} }
if (proxyField->hasSetter()) if (proxyField->hasSetter())
{ {
QString fullComment = QString(" \"\"\"Set %1\n Attributes:\n" QString fullComment = QString(" \"\"\"Set %1\n Arguments:\n"
" values (%2): data\n \"\"\"") " values (%2): data\n \"\"\"")
.arg(comment) .arg(comment)
.arg(dataTypeString); .arg(dataType);
QString fieldCode = QString(" def set_%1(self, values):\n%2\n " QString fieldCode = QString(" def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n") "self._call_set_method(\"%3\", values)\n")
@ -172,10 +175,17 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
} }
else else
{ {
QString fieldCode = QString(" self.%1 = None\n").arg(snake_field_name); QString valueString;
QTextStream valueStream(&valueString);
scriptability->writeFieldData(valueStream, true, true);
if (valueString.isEmpty())
valueString = QString("\"\"");
valueString = pythonifyDataValue(valueString);
QString fieldCode = QString(" self.%1 = %2\n").arg(snake_field_name).arg(valueString);
QString fullComment = QString fullComment =
QString("%1 (%2): %3\n").arg(snake_field_name).arg(dataTypeString).arg(comment); QString("%1 (%2): %3\n").arg(snake_field_name).arg(dataType).arg(comment);
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode; classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment; classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment;
@ -296,3 +306,60 @@ QString PdmPythonGenerator::camelToSnakeCase(const QString& camelString)
snake_case.replace(re2, "\\1_\\2"); snake_case.replace(re2, "\\1_\\2");
return snake_case.toLower(); return snake_case.toLower();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool* isList, bool* isBuiltinType)
{
auto xmlObj = field->capability<PdmXmlFieldHandle>();
QString dataType = xmlObj->childClassKeyword();
bool foundList = xmlObj->isVectorField();
std::map<QString, QString> builtins =
{ {QString::fromStdString(typeid(double).name()), "float"},
{QString::fromStdString(typeid(float).name()), "float"},
{QString::fromStdString(typeid(int).name()), "int"},
{QString::fromStdString(typeid(QString).name()), "str"}
};
bool foundBuiltin = false;
for (auto builtin : builtins)
{
if (dataType == builtin.first)
{
dataType.replace(builtin.first, builtin.second);
foundBuiltin = true;
}
}
if (isList)
{
*isList = foundList;
}
if (isBuiltinType)
{
*isBuiltinType = foundBuiltin;
}
if (!foundBuiltin)
{
dataType = "str";
}
if (foundList) return QString("List of %1").arg(dataType);
return dataType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString caf::PdmPythonGenerator::pythonifyDataValue(const QString& dataValue)
{
QString outValue = dataValue;
outValue.replace("false", "False");
outValue.replace("true", "True");
return outValue;
}

View File

@ -39,6 +39,8 @@
namespace caf { namespace caf {
class PdmFieldHandle;
//================================================================================================== //==================================================================================================
/// Python skeleton generator from Project Data Model /// Python skeleton generator from Project Data Model
//================================================================================================== //==================================================================================================
@ -48,6 +50,9 @@ class PdmPythonGenerator : public PdmCodeGenerator
public: public:
QString generate(PdmObjectFactory* factory) const override; QString generate(PdmObjectFactory* factory) const override;
static QString camelToSnakeCase(const QString& camelString); static QString camelToSnakeCase(const QString& camelString);
static QString dataTypeString(const PdmFieldHandle* field, bool* isList = nullptr, bool* isBuiltinType = nullptr);
static QString pythonifyDataValue(const QString& dataValue);
}; };
} }

View File

@ -19,6 +19,7 @@ template< typename T> class PdmFieldXmlCap;
class PdmChildFieldHandle : public PdmFieldHandle class PdmChildFieldHandle : public PdmFieldHandle
{ {
public: public:
virtual void childObjects(std::vector<PdmObjectHandle*>* objects) = 0;
virtual void setChildObject(PdmObjectHandle* object) = 0; virtual void setChildObject(PdmObjectHandle* object) = 0;
}; };

View File

@ -45,6 +45,7 @@
#include <QVariant> #include <QVariant>
#include <typeinfo>
#include <vector> #include <vector>
@ -62,6 +63,10 @@ template<typename DataType >
class PdmDataValueField : public PdmValueField class PdmDataValueField : public PdmValueField
{ {
public: public:
// Type traits magic to check if a template argument is a vector
template<typename T> struct is_vector : public std::false_type {};
template<typename T, typename A> struct is_vector<std::vector<T, A>> : public std::true_type {};
typedef DataType FieldDataType; typedef DataType FieldDataType;
PdmDataValueField() {} PdmDataValueField() {}
PdmDataValueField(const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; } PdmDataValueField(const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; }
@ -95,6 +100,7 @@ public:
bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; } bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; }
bool operator!= (const DataType& fieldValue) const { return m_fieldValue != fieldValue; } bool operator!= (const DataType& fieldValue) const { return m_fieldValue != fieldValue; }
protected: protected:
DataType m_fieldValue; DataType m_fieldValue;

View File

@ -27,12 +27,6 @@ public:
virtual bool hasSetter() const = 0; virtual bool hasSetter() const = 0;
}; };
//==================================================================================================
/// Type traits magic to check if a template argument is a vector
//==================================================================================================
template<typename T> struct is_vector : public std::false_type {};
template<typename T, typename A> struct is_vector<std::vector<T, A>> : public std::true_type{};
//================================================================================================== //==================================================================================================
/// Field class encapsulating data access through object setter/getter with input and output of this /// Field class encapsulating data access through object setter/getter with input and output of this
/// data to/from a QXmlStream /// data to/from a QXmlStream
@ -42,6 +36,10 @@ template<typename DataType >
class PdmProxyValueField : public PdmProxyFieldHandle class PdmProxyValueField : public PdmProxyFieldHandle
{ {
public: public:
// Type traits magic to check if a template argument is a vector
template<typename T> struct is_vector : public std::false_type {};
template<typename T, typename A> struct is_vector<std::vector<T, A>> : public std::true_type {};
typedef DataType FieldDataType; typedef DataType FieldDataType;
PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; } PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; }
~PdmProxyValueField() override { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; } ~PdmProxyValueField() override { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; }

View File

@ -3,6 +3,8 @@
#include "cafInternalPdmXmlFieldReaderWriter.h" #include "cafInternalPdmXmlFieldReaderWriter.h"
#include "cafPdmXmlFieldHandle.h" #include "cafPdmXmlFieldHandle.h"
#include <typeinfo>
namespace caf namespace caf
{ {
@ -10,7 +12,11 @@ template < typename FieldType>
class PdmFieldXmlCap : public PdmXmlFieldHandle class PdmFieldXmlCap : public PdmXmlFieldHandle
{ {
public: public:
PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; } PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership)
{
m_field = field;
m_childClassKeyword = QString("%1").arg(typeid(FieldType).name());
}
// Xml Serializing // Xml Serializing
public: public:
@ -18,11 +24,12 @@ public:
void writeFieldData(QXmlStreamWriter& xmlStream) const override; void writeFieldData(QXmlStreamWriter& xmlStream) const override;
bool resolveReferences() override; bool resolveReferences() override;
bool isVectorField() const;
private: private:
FieldType* m_field; FieldType* m_field;
}; };
template <typename DataType> class PdmPtrField; template <typename DataType> class PdmPtrField;
template < typename DataType> template < typename DataType>

View File

@ -15,6 +15,16 @@ namespace caf
/// ///
//================================================================================================== //==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template < typename FieldType>
bool caf::PdmFieldXmlCap<FieldType>::isVectorField() const
{
return is_vector<FieldType>();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -53,10 +53,10 @@ void PdmXmlFieldHandle::disableIO()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Returns the classKeyword of the child class type, if this field is supposed to contain pointers /// Returns the classKeyword of the child class type, if this field is supposed to contain pointers
/// to PdmObjectHandle derived onbjects. /// to PdmObjectHandle derived objects.
/// Returns empty string if the field is not containig some PdmObjectHandle type /// Returns typeid(DataType).name() if the field is not containing some PdmObjectHandle type
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString PdmXmlFieldHandle::childClassKeyword() QString PdmXmlFieldHandle::childClassKeyword() const
{ {
return m_childClassKeyword; return m_childClassKeyword;
} }

View File

@ -22,6 +22,11 @@ class PdmReferenceHelper;
//================================================================================================== //==================================================================================================
class PdmXmlFieldHandle : public PdmFieldCapability class PdmXmlFieldHandle : public PdmFieldCapability
{ {
public:
// Type traits magic to check if a template argument is a vector
template<typename T> struct is_vector : public std::false_type {};
template<typename T, typename A> struct is_vector<std::vector<T, A>> : public std::true_type {};
public: public:
PdmXmlFieldHandle(PdmFieldHandle* owner , bool giveOwnership); PdmXmlFieldHandle(PdmFieldHandle* owner , bool giveOwnership);
~PdmXmlFieldHandle() override { } ~PdmXmlFieldHandle() override { }
@ -33,12 +38,14 @@ public:
bool isIOWritable() const { return m_isIOWritable; } bool isIOWritable() const { return m_isIOWritable; }
bool isCopyable() const { return m_isCopyable;} bool isCopyable() const { return m_isCopyable;}
virtual bool isVectorField() const { return false; }
void disableIO(); void disableIO();
void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; }
void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; }
void setCopyable(bool isCopyable) { m_isCopyable = isCopyable; } void setCopyable(bool isCopyable) { m_isCopyable = isCopyable; }
QString childClassKeyword(); QString childClassKeyword() const;
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0; virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0;
virtual void writeFieldData(QXmlStreamWriter& xmlStream) const = 0; virtual void writeFieldData(QXmlStreamWriter& xmlStream) const = 0;