File indexing completed on 2024-05-12 04:37:46

0001 /*
0002     SPDX-FileCopyrightText: 2012 Miha Čančula <miha@noughmad.eu>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "codedescription.h"
0008 #include <debug.h>
0009 #include <language/duchain/duchainutils.h>
0010 #include <language/duchain/duchainlock.h>
0011 #include <language/duchain/duchain.h>
0012 #include <language/duchain/declaration.h>
0013 #include <language/duchain/types/functiontype.h>
0014 #include <language/duchain/classfunctiondeclaration.h>
0015 #include <language/duchain/functiondeclaration.h>
0016 
0017 #include <KLocalizedString>
0018 
0019 using namespace KDevelop;
0020 
0021 /**
0022  * The access policy as a string, or an empty string
0023  * if the policy is set to default
0024  *
0025  * The DUChain must be locked when calling this function
0026  **/
0027 QString accessPolicyName(const DeclarationPointer& declaration)
0028 {
0029     DUChainPointer<ClassMemberDeclaration> member = declaration.dynamicCast<ClassMemberDeclaration>();
0030     if (member) {
0031         switch (member->accessPolicy())
0032         {
0033         case Declaration::Private:
0034             return QStringLiteral("private");
0035         case Declaration::Protected:
0036             return QStringLiteral("protected");
0037         case Declaration::Public:
0038             return QStringLiteral("public");
0039         default:
0040             break;
0041         }
0042     }
0043     return QString();
0044 }
0045 
0046 VariableDescription::VariableDescription()
0047 {
0048 }
0049 
0050 VariableDescription::VariableDescription(const QString& type, const QString& name)
0051     : name(name)
0052     , type(type)
0053 {
0054 }
0055 
0056 VariableDescription::VariableDescription(const DeclarationPointer& declaration)
0057 {
0058     DUChainReadLocker lock;
0059 
0060     if (declaration) {
0061         name = declaration->identifier().toString();
0062         if (auto abstractType = declaration->abstractType()) {
0063             type = abstractType->toString();
0064         }
0065     }
0066 
0067     access = accessPolicyName(declaration);
0068 }
0069 
0070 FunctionDescription::FunctionDescription()
0071     : FunctionDescription::FunctionDescription({}, {}, {})
0072 {
0073 }
0074 
0075 FunctionDescription::FunctionDescription(const QString& name, const VariableDescriptionList& arguments,
0076                                          const VariableDescriptionList& returnArguments)
0077     : name(name)
0078     , arguments(arguments)
0079     , returnArguments(returnArguments)
0080     , isConstructor(false)
0081     , isDestructor(false)
0082     , isVirtual(false)
0083     , isStatic(false)
0084     , isSlot(false)
0085     , isSignal(false)
0086     , isConst(false)
0087 {
0088 }
0089 
0090 FunctionDescription::FunctionDescription(const DeclarationPointer& declaration)
0091     : FunctionDescription::FunctionDescription({}, {}, {})
0092 {
0093     DUChainReadLocker lock;
0094 
0095     if (declaration) {
0096         name = declaration->identifier().toString();
0097         DUContext* context = declaration->internalContext();
0098 
0099         DUChainPointer<FunctionDeclaration> function = declaration.dynamicCast<FunctionDeclaration>();
0100         if (function) {
0101             context = DUChainUtils::argumentContext(declaration.data());
0102         }
0103 
0104         DUChainPointer<ClassFunctionDeclaration> method = declaration.dynamicCast<ClassFunctionDeclaration>();
0105 
0106         if (method) {
0107             isConstructor = method->isConstructor();
0108             isDestructor = method->isDestructor();
0109             isVirtual = method->isVirtual();
0110             isAbstract = method->isAbstract();
0111             isFinal = method->isFinal();
0112             isOverriding = (DUChainUtils::overridden(method.data()) != nullptr);
0113             isStatic = method->isStatic();
0114             isSlot = method->isSlot();
0115             isSignal = method->isSignal();
0116         }
0117 
0118         int i = 0;
0119         const auto localDeclarations = context->localDeclarations();
0120         arguments.reserve(localDeclarations.size());
0121         for (Declaration* arg : localDeclarations) {
0122             VariableDescription var = VariableDescription(DeclarationPointer(arg));
0123             if (function) {
0124                 var.value = function->defaultParameterForArgument(i).str();
0125                 qCDebug(LANGUAGE) << var.name << var.value;
0126             }
0127             arguments << var;
0128             ++i;
0129         }
0130 
0131         auto functionType = declaration->abstractType().dynamicCast<FunctionType>();
0132 
0133         if (functionType) {
0134             isConst = (functionType->modifiers() & AbstractType::ConstModifier);
0135         }
0136 
0137         if (functionType && functionType->returnType()) {
0138             returnArguments << VariableDescription(functionType->returnType()->toString(), QString());
0139         }
0140 
0141         access = accessPolicyName(declaration);
0142     }
0143 }
0144 
0145 QString FunctionDescription::returnType() const
0146 {
0147     if (returnArguments.isEmpty()) {
0148         return QString();
0149     }
0150     return returnArguments.first().type;
0151 }
0152 
0153 ClassDescription::ClassDescription()
0154 {
0155 }
0156 
0157 ClassDescription::ClassDescription(const QString& name)
0158     : name(name)
0159 {
0160 }