File indexing completed on 2024-11-10 04:40:46
0001 /* 0002 SPDX-FileCopyrightText: 2017 Daniel Vrátil <dvratil@kde.og> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "nodetree.h" 0008 #include "cpphelper.h" 0009 #include "typehelper.h" 0010 0011 namespace 0012 { 0013 0014 QString qualifiedName(const Node *node) 0015 { 0016 if (node->type() == Node::Class) { 0017 return static_cast<const ClassNode *>(node)->className(); 0018 } 0019 if (node->type() == Node::Enum) { 0020 auto enumNode = static_cast<const EnumNode *>(node); 0021 if (enumNode->enumType() == EnumNode::TypeFlag) { 0022 return QStringLiteral("%1::%2").arg(qualifiedName(node->parent()), enumNode->flagsName()); 0023 } 0024 return QStringLiteral("%1::%2").arg(qualifiedName(node->parent()), enumNode->name()); 0025 } 0026 0027 Q_ASSERT_X(false, "qualifiedName", "Invalid node type"); 0028 return {}; 0029 } 0030 0031 } // namespace 0032 0033 Node::Node(NodeType type, Node *parent) 0034 : mParent(parent) 0035 , mType(type) 0036 { 0037 if (parent) { 0038 parent->appendNode(this); 0039 } 0040 } 0041 0042 Node::~Node() 0043 { 0044 qDeleteAll(mChildren); 0045 } 0046 0047 Node::NodeType Node::type() const 0048 { 0049 return mType; 0050 } 0051 0052 Node *Node::parent() const 0053 { 0054 return mParent; 0055 } 0056 0057 void Node::appendNode(Node *child) 0058 { 0059 child->mParent = this; 0060 mChildren.push_back(child); 0061 } 0062 0063 const QList<Node const *> &Node::children() const 0064 { 0065 return mChildren; 0066 } 0067 0068 DocumentNode::DocumentNode(int version) 0069 : Node(Document, nullptr) 0070 , mVersion(version) 0071 { 0072 } 0073 0074 int DocumentNode::version() const 0075 { 0076 return mVersion; 0077 } 0078 0079 ClassNode::ClassNode(const QString &name, ClassType type, DocumentNode *parent) 0080 : Node(Node::Class, parent) 0081 , mName(name) 0082 , mClassType(type) 0083 { 0084 } 0085 0086 QString ClassNode::name() const 0087 { 0088 return mName; 0089 } 0090 0091 ClassNode::ClassType ClassNode::classType() const 0092 { 0093 return mClassType; 0094 } 0095 0096 QString ClassNode::className() const 0097 { 0098 switch (mClassType) { 0099 case Class: 0100 return mName; 0101 case Command: 0102 return mName + QStringLiteral("Command"); 0103 case Response: 0104 return mName + QStringLiteral("Response"); 0105 case Notification: 0106 return mName + QStringLiteral("Notification"); 0107 default: 0108 Q_ASSERT(false); 0109 return QString(); 0110 } 0111 } 0112 0113 QString ClassNode::parentClassName() const 0114 { 0115 switch (mClassType) { 0116 case Class: 0117 return QString(); 0118 case Command: 0119 return QStringLiteral("Command"); 0120 case Response: 0121 return QStringLiteral("Response"); 0122 case Notification: 0123 return QStringLiteral("ChangeNotification"); 0124 case Invalid: 0125 Q_ASSERT(false); 0126 return QString(); 0127 } 0128 Q_UNREACHABLE(); 0129 } 0130 0131 ClassNode::ClassType ClassNode::elementNameToType(QStringView name) 0132 { 0133 if (name == QLatin1StringView("class")) { 0134 return Class; 0135 } else if (name == QLatin1StringView("command")) { 0136 return Command; 0137 } else if (name == QLatin1StringView("response")) { 0138 return Response; 0139 } else if (name == QLatin1StringView("notification")) { 0140 return Notification; 0141 } else { 0142 return Invalid; 0143 } 0144 } 0145 0146 QList<PropertyNode const *> ClassNode::properties() const 0147 { 0148 QList<const PropertyNode *> rv; 0149 for (const auto node : std::as_const(mChildren)) { 0150 if (node->type() == Node::Property) { 0151 rv << static_cast<PropertyNode const *>(node); 0152 } 0153 } 0154 CppHelper::sortMembers(rv); 0155 return rv; 0156 } 0157 0158 CtorNode::CtorNode(const QList<Argument> &args, ClassNode *parent) 0159 : Node(Ctor, parent) 0160 , mArgs(args) 0161 { 0162 } 0163 0164 CtorNode::~CtorNode() 0165 { 0166 } 0167 0168 QList<CtorNode::Argument> CtorNode::arguments() const 0169 { 0170 return mArgs; 0171 } 0172 0173 void CtorNode::setArgumentType(const QString &name, const QString &type) 0174 { 0175 for (auto &arg : mArgs) { 0176 if (arg.name == name) { 0177 arg.type = type; 0178 break; 0179 } 0180 } 0181 } 0182 0183 EnumNode::EnumNode(const QString &name, EnumType type, ClassNode *parent) 0184 : Node(Enum, parent) 0185 , mName(name) 0186 , mEnumType(type) 0187 { 0188 } 0189 0190 QString EnumNode::name() const 0191 { 0192 return mName; 0193 } 0194 0195 EnumNode::EnumType EnumNode::enumType() const 0196 { 0197 return mEnumType; 0198 } 0199 0200 QString EnumNode::flagsName() const 0201 { 0202 if (mEnumType == TypeFlag) { 0203 return mName + QStringLiteral("s"); 0204 } 0205 0206 return {}; 0207 } 0208 0209 EnumNode::EnumType EnumNode::elementNameToType(QStringView name) 0210 { 0211 if (name == QLatin1StringView("enum")) { 0212 return TypeEnum; 0213 } else if (name == QLatin1StringView("flag")) { 0214 return TypeFlag; 0215 } else { 0216 return TypeInvalid; 0217 } 0218 } 0219 0220 EnumValueNode::EnumValueNode(const QString &name, EnumNode *parent) 0221 : Node(EnumValue, parent) 0222 , mName(name) 0223 , mValue() 0224 { 0225 } 0226 0227 QString EnumValueNode::name() const 0228 { 0229 return mName; 0230 } 0231 0232 void EnumValueNode::setValue(const QString &value) 0233 { 0234 mValue = value; 0235 } 0236 0237 QString EnumValueNode::value() const 0238 { 0239 return mValue; 0240 } 0241 0242 PropertyNode::PropertyNode(const QString &name, const QString &type, ClassNode *parent) 0243 : Node(Property, parent) 0244 , mName(name) 0245 , mType(type) 0246 , mSetter(nullptr) 0247 , mReadOnly(false) 0248 , mAsReference(false) 0249 { 0250 } 0251 0252 PropertyNode::~PropertyNode() 0253 { 0254 delete mSetter; 0255 } 0256 0257 QString PropertyNode::type() const 0258 { 0259 return mType; 0260 } 0261 0262 QString PropertyNode::name() const 0263 { 0264 return mName; 0265 } 0266 0267 void PropertyNode::setDefaultValue(const QString &defaultValue) 0268 { 0269 mDefaultValue = defaultValue; 0270 } 0271 0272 QString PropertyNode::defaultValue() const 0273 { 0274 return mDefaultValue; 0275 } 0276 0277 bool PropertyNode::readOnly() const 0278 { 0279 return mReadOnly; 0280 } 0281 0282 void PropertyNode::setReadOnly(bool readOnly) 0283 { 0284 mReadOnly = readOnly; 0285 } 0286 0287 bool PropertyNode::asReference() const 0288 { 0289 return mAsReference; 0290 } 0291 0292 void PropertyNode::setAsReference(bool asReference) 0293 { 0294 mAsReference = asReference; 0295 } 0296 0297 bool PropertyNode::isPointer() const 0298 { 0299 return TypeHelper::isPointerType(mType); 0300 } 0301 0302 bool PropertyNode::isEnum() const 0303 { 0304 auto parentClass = static_cast<ClassNode *>(parent()); 0305 for (const auto node : parentClass->children()) { 0306 if (node->type() == Node::Enum) { 0307 const auto enumNode = static_cast<const EnumNode *>(node); 0308 if (qualifiedName(enumNode) == mType) { 0309 return true; 0310 } 0311 } 0312 } 0313 0314 return false; 0315 } 0316 0317 QMultiMap<QString, QString> PropertyNode::dependencies() const 0318 { 0319 return mDepends; 0320 } 0321 0322 void PropertyNode::addDependency(const QString &enumVar, const QString &enumValue) 0323 { 0324 mDepends.insert(enumVar, enumValue); 0325 } 0326 0327 void PropertyNode::setSetter(Setter *setter) 0328 { 0329 mSetter = setter; 0330 } 0331 0332 PropertyNode::Setter *PropertyNode::setter() const 0333 { 0334 return mSetter; 0335 } 0336 0337 QString PropertyNode::mVariableName() const 0338 { 0339 return QStringLiteral("m") + mName[0].toUpper() + QStringView(mName).mid(1); 0340 } 0341 0342 QString PropertyNode::setterName() const 0343 { 0344 return QStringLiteral("set") + mName[0].toUpper() + QStringView(mName).mid(1); 0345 }