File indexing completed on 2024-04-21 15:24:06
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0003 SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "helpers.h" 0009 #include "item.h" 0010 0011 #include <QList> 0012 #include <QVariant> 0013 #include <QTextFormat> 0014 #include <QStringList> 0015 0016 #include <language/duchain/declaration.h> 0017 #include <language/duchain/abstractfunctiondeclaration.h> 0018 #include <language/duchain/duchainutils.h> 0019 #include <language/duchain/ducontext.h> 0020 #include <language/duchain/types/functiontype.h> 0021 #include <language/duchain/types/integraltype.h> 0022 0023 #include <KTextEditor/ConfigInterface> 0024 #include <KTextEditor/Document> 0025 0026 using namespace KDevelop; 0027 namespace Php 0028 { 0029 0030 void createArgumentList(const NormalDeclarationCompletionItem& item, QString& ret, QList<QVariant>* highlighting, 0031 bool phpTypeHinting) 0032 { 0033 ///@todo also highlight the matches of the previous arguments, they are given by ViableFunction 0034 Declaration* dec(item.declaration().data()); 0035 0036 int textFormatStart = 0; 0037 QTextFormat normalFormat(QTextFormat::CharFormat); 0038 QTextFormat highlightFormat; //highlightFormat is invalid, so kate uses the match-quality dependent color. 0039 0040 AbstractFunctionDeclaration* decl = dynamic_cast<AbstractFunctionDeclaration*>(dec); 0041 FunctionType::Ptr functionType = dec->type<FunctionType>(); 0042 0043 if (functionType && decl) { 0044 0045 QVector<Declaration*> parameters; 0046 if (DUChainUtils::argumentContext(dec)) 0047 parameters = DUChainUtils::argumentContext(dec)->localDeclarations(); 0048 0049 uint defaultParamNum = 0; 0050 0051 int firstDefaultParam = parameters.count() - decl->defaultParametersSize(); 0052 0053 ret = '('; 0054 bool first = true; 0055 int num = 0; 0056 0057 foreach(Declaration* dec, parameters) { 0058 if (first) 0059 first = false; 0060 else 0061 ret += QLatin1String(", "); 0062 0063 bool doHighlight = false; 0064 QTextFormat doFormat = normalFormat; 0065 0066 // if( num < f.matchedArguments ) 0067 // { 0068 doHighlight = true; 0069 doFormat = QTextFormat(QTextFormat::CharFormat); 0070 0071 // if( parameterConversion != conversions.end() ) { 0072 // //Interpolate the color 0073 // quint64 badMatchColor = 0xff7777ff; //Full blue 0074 // quint64 goodMatchColor = 0xff77ff77; //Full green 0075 // 0076 // uint totalColor = (badMatchColor*(Cpp::MaximumConversionResult-(*parameterConversion).rank) + goodMatchColor*(*parameterConversion).rank)/Cpp::MaximumConversionResult; 0077 // 0078 // doFormat.setBackground( QBrush(totalColor) ); 0079 // 0080 // ++parameterConversion; 0081 // } 0082 // } 0083 0084 if (doHighlight) { 0085 if (highlighting && ret.length() != textFormatStart) { 0086 //Add a default-highlighting for the passed text 0087 *highlighting << QVariant(textFormatStart); 0088 *highlighting << QVariant(ret.length() - textFormatStart); 0089 *highlighting << QVariant(normalFormat); 0090 textFormatStart = ret.length(); 0091 } 0092 } 0093 0094 if (num < functionType->arguments().count()) { 0095 if (AbstractType::Ptr type = functionType->arguments().at(num)) { 0096 // when php-like type hinting is requested only add types for arrays and classes 0097 if (!phpTypeHinting 0098 || (type->whichType() == AbstractType::TypeIntegral 0099 && type.staticCast<IntegralType>()->dataType() == IntegralType::TypeArray) 0100 || type->whichType() == AbstractType::TypeStructure) { 0101 ret += type->toString() + ' '; 0102 } 0103 } 0104 } 0105 0106 ret += '$' + dec->identifier().toString(); 0107 0108 if (doHighlight) { 0109 if (highlighting && ret.length() != textFormatStart) { 0110 *highlighting << QVariant(textFormatStart); 0111 *highlighting << QVariant(ret.length() - textFormatStart); 0112 *highlighting << doFormat; 0113 textFormatStart = ret.length(); 0114 } 0115 } 0116 0117 0118 if (num >= firstDefaultParam) { 0119 IndexedString defaultStr = decl->defaultParameters()[defaultParamNum]; 0120 if (!defaultStr.isEmpty()) { 0121 ret += " = " + defaultStr.str(); 0122 } 0123 ++defaultParamNum; 0124 } 0125 0126 ++num; 0127 } 0128 ret += ')'; 0129 0130 if (highlighting && ret.length() != textFormatStart) { 0131 *highlighting << QVariant(textFormatStart); 0132 *highlighting << QVariant(ret.length()); 0133 *highlighting << normalFormat; 0134 textFormatStart = ret.length(); 0135 } 0136 return; 0137 } 0138 } 0139 0140 QStringList getMethodTokens(QString text) 0141 { 0142 QStringList tokens; 0143 0144 0145 text = text.trimmed(); 0146 if (text.endsWith(QStringLiteral("function"), Qt::CaseInsensitive)) { 0147 tokens << QStringLiteral("function"); 0148 text = text.left(text.length() - 8); 0149 } 0150 0151 QStringList possibleTokens; 0152 possibleTokens << QStringLiteral("private"); 0153 possibleTokens << QStringLiteral("public"); 0154 possibleTokens << QStringLiteral("protected"); 0155 possibleTokens << QStringLiteral("static"); 0156 possibleTokens << QStringLiteral("abstract"); 0157 possibleTokens << QStringLiteral("final"); 0158 0159 while (!possibleTokens.isEmpty()) { 0160 bool foundAnything = false; 0161 text = text.trimmed(); 0162 foreach(const QString &token, possibleTokens) { 0163 if (text.endsWith(token, Qt::CaseInsensitive)) { 0164 tokens << token; 0165 text = text.left(text.length() - token.length()); 0166 foundAnything = true; 0167 possibleTokens.removeOne(token); 0168 break; 0169 } 0170 } 0171 if (!foundAnything) { 0172 break; 0173 } 0174 } 0175 0176 return tokens; 0177 } 0178 0179 const QString indentString(KTextEditor::Document *document) 0180 { 0181 KTextEditor::ConfigInterface *iface = qobject_cast<KTextEditor::ConfigInterface *>(document); 0182 if (!iface) 0183 return QStringLiteral(" "); 0184 if (iface->configValue(QStringLiteral("replace-tabs")).toBool()) { 0185 QVariant iWidth = iface->configValue(QStringLiteral("indent-width")); 0186 if (iWidth.isValid()) 0187 return QString(iWidth.toUInt(), ' '); 0188 /* 0189 * Provide a default implementation if current KatePart 0190 * does not handle "indent-width". 0191 */ 0192 return QStringLiteral(" "); 0193 } 0194 return QStringLiteral("\t"); 0195 } 0196 0197 QString getIndentation( const QString &line ) { 0198 return line.left(line.indexOf(QRegExp("\\S"), 0)); 0199 } 0200 0201 }