File indexing completed on 2024-05-12 04:37:44
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #include "codecompletionhelper.h" 0008 0009 #include "../duchain/duchain.h" 0010 #include "../duchain/declaration.h" 0011 #include "../duchain/duchainlock.h" 0012 #include "../duchain/types/functiontype.h" 0013 #include "../duchain/types/integraltype.h" 0014 0015 #include <KTextEditor/Document> 0016 #include <KTextEditor/View> 0017 0018 namespace KDevelop { 0019 void insertFunctionParenText(KTextEditor::View* view, const KTextEditor::Cursor& pos, 0020 const DeclarationPointer& declaration, bool jumpForbidden) 0021 { 0022 bool spaceBeforeParen = false; ///@todo Take this from some astyle config or something 0023 bool spaceBetweenParens = false; 0024 bool spaceBetweenEmptyParens = false; 0025 0026 KDevelop::DUChainReadLocker lock(KDevelop::DUChain::lock()); 0027 0028 bool haveArguments = false; 0029 0030 if (!declaration) 0031 return; 0032 0033 TypePtr<FunctionType> funcType = declaration->type<FunctionType>(); 0034 0035 if (declaration->kind() == Declaration::Type || (funcType && funcType->indexedArgumentsSize())) 0036 haveArguments = true; 0037 0038 if (declaration->kind() == Declaration::Instance && !declaration->isFunctionDeclaration()) 0039 haveArguments = true; //probably a constructor initializer 0040 0041 //Need to have a paren behind 0042 QString suffix = view->document()->text(KTextEditor::Range(pos, pos + KTextEditor::Cursor(1, 0))); 0043 if (suffix.trimmed().startsWith(QLatin1Char('('))) { 0044 //Move the cursor behind the opening paren 0045 if (view) 0046 view->setCursorPosition(pos + KTextEditor::Cursor(0, suffix.indexOf(QLatin1Char('(')) + 1)); 0047 } else { 0048 //We need to insert an opening paren 0049 QString openingParen; 0050 if (spaceBeforeParen) 0051 openingParen = QStringLiteral(" ("); 0052 else 0053 openingParen = QStringLiteral("("); 0054 0055 if (spaceBetweenParens && (haveArguments || spaceBetweenEmptyParens)) 0056 openingParen += QLatin1Char(' '); 0057 0058 QString closingParen; 0059 if (spaceBetweenParens && (haveArguments)) { 0060 closingParen = QStringLiteral(" )"); 0061 } else 0062 closingParen = QStringLiteral(")"); 0063 0064 KTextEditor::Cursor jumpPos = pos + KTextEditor::Cursor(0, openingParen.length()); 0065 0066 // when function returns void, also add a semicolon 0067 if (funcType) { 0068 if (auto type = funcType->returnType().dynamicCast<IntegralType>()) { 0069 if (type->dataType() == IntegralType::TypeVoid) { 0070 const QChar nextChar = view->document()->characterAt(pos); 0071 if (nextChar != QLatin1Char(';') && nextChar != QLatin1Char(')') && nextChar != QLatin1Char(',')) { 0072 closingParen += QLatin1Char(';'); 0073 } 0074 } 0075 } 0076 } 0077 0078 //If no arguments, move the cursor behind the closing paren (or semicolon) 0079 if (!haveArguments) 0080 jumpPos += KTextEditor::Cursor(0, closingParen.length()); 0081 0082 lock.unlock(); 0083 if (view) { 0084 view->document()->insertText(pos, openingParen + closingParen); 0085 if (!jumpForbidden) { 0086 view->setCursorPosition(jumpPos); 0087 } 0088 } 0089 } 0090 } 0091 }