From 894e587f7d4647ef538abb851059b7e52fdea472 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Wed, 26 Jan 2022 12:17:15 +0800 Subject: [PATCH] - enhancement: show parameter tips for class constructors - enhancement: when there are tips showing, don't show mouse tips --- NEWS.md | 2 ++ RedPandaIDE/editor.cpp | 37 +++++++++++++++++++++++++++++- RedPandaIDE/mainwindow.cpp | 2 +- RedPandaIDE/parser/cppparser.cpp | 29 ++++++++++++++++------- RedPandaIDE/parser/cppparser.h | 2 ++ RedPandaIDE/parser/parserutils.cpp | 2 +- RedPandaIDE/parser/parserutils.h | 2 +- 7 files changed, 64 insertions(+), 12 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8ecb36b6..d0c7d855 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,8 @@ Red Panda C++ Version 0.13.4 - fix: can't show private & protected members of 'this' - fix: function name like 'A::B' is not correctly parsed - fix: static members are not correct shown after Classname + '::' + - enhancement: show parameter tips for class constructors + - enhancement: when there are tips showing, don't show mouse tips Red Panda C++ Version 0.13.3 - enhancement: restore editor position after rename symbol diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 3b042902..4a514bf1 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -957,7 +957,9 @@ bool Editor::event(QEvent *event) { if ((event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove) && pSettings->editor().enableTooltips() - ) { + && !pMainWindow->completionPopup()->isVisible() + && !pMainWindow->functionTip()->isVisible() + && !pMainWindow->headerCompletionPopup()->isVisible()) { QHoverEvent *helpEvent = static_cast(event); BufferCoord p; TipType reason = getTipType(helpEvent->pos(),p); @@ -3366,6 +3368,39 @@ void Editor::updateFunctionTip() QString s = getWordAtPosition(this, functionNamePos, pWordBegin,pWordEnd, WordPurpose::wpInformation); + int x = pWordBegin.Char-1-1; + QString line = lines()->getString(pWordBegin.Line-1); + bool hasPreviousWord=false; + while (x>=0) { + QChar ch=line[x]; + if (ch == ' ' || ch == '\t') + continue; + if (isIdentChar(ch)) { + hasPreviousWord = true; + break; + } + hasPreviousWord = false; + break; + } + + if (x >= 0 && hasPreviousWord) { + BufferCoord pos = pWordBegin; + pos.Char = x+1; + QString previousWord = getPreviousWordAtPositionForSuggestion(pos); + + PStatement statement = mParser->findStatementOf( + mFilename, + previousWord, + pos.Line); + if (statement) { + PStatement typeStatement = mParser->findTypeDef(statement,mFilename); + if (typeStatement && typeStatement->kind == StatementKind::skClass) { + s = previousWord; + functionNamePos = pos; + } + } + } + // qDebug()< CppParser::getListOfFunctions(const QString &fileName, const Q PStatement statement = findStatementOf(fileName,phrase, line); if (!statement) return result; - PStatement parentScope = statement->parentScope.lock(); + PStatement parentScope; + if (statement->kind == StatementKind::skClass) { + parentScope = statement; + } else + parentScope = statement->parentScope.lock(); if (parentScope && parentScope->kind == StatementKind::skNamespace) { PStatementList namespaceStatementsList = findNamespace(parentScope->command); if (namespaceStatementsList) { @@ -545,6 +549,15 @@ PStatement CppParser::findTypeDefinitionOf(const QString &fileName, const QStrin return getTypeDef(statement,fileName,aType); } +PStatement CppParser::findTypeDef(const PStatement &statement, const QString &fileName) +{ + QMutexLocker locker(&mMutex); + + if (mParsing) + return PStatement(); + return getTypeDef(statement, fileName, ""); +} + bool CppParser::freeze() { QMutexLocker locker(&mMutex); @@ -3323,12 +3336,12 @@ QList CppParser::getListOfFunctions(const QString &fileName, int lin QList result; StatementMap children = mStatementList.childrenStatements(scopeStatement); for (const PStatement& child:children) { - if ((statement->command == child->command) + if (( (statement->command == child->command) #ifdef Q_OS_WIN || (statement->command +'A' == child->command) || (statement->command +'W' == child->command) #endif - ) { + ) ) { if (line < child->line && (child->fileName == fileName)) continue; result.append(child); @@ -4473,7 +4486,7 @@ QString CppParser::removeArgNames(const QString &args) if (!typeGetted) { currentArg += ' ' + word; } else { - if (isKeyword(word)) { + if (isCppKeyword(word)) { currentArg += ' ' + word; } } @@ -4502,10 +4515,10 @@ QString CppParser::removeArgNames(const QString &args) } else if (!word.trimmed().isEmpty()) { if (!typeGetted) { currentArg += ' ' + word; - if (mCppTypeKeywords.contains(word) || !isKeyword(word)) + if (mCppTypeKeywords.contains(word) || !isCppKeyword(word)) typeGetted = true; } else { - if (isKeyword(word)) + if (isCppKeyword(word)) currentArg += ' ' + word; } word = ""; @@ -4520,7 +4533,7 @@ QString CppParser::removeArgNames(const QString &args) if (!typeGetted) { currentArg += ' ' + word; } else { - if (isKeyword(word)) { + if (isCppKeyword(word)) { currentArg += ' ' + word; } } @@ -4650,7 +4663,7 @@ bool CppParser::isNotFuncArgs(const QString &args) return false; } - if (isKeyword(word)) { + if (isCppKeyword(word)) { return word == "true" || word == "false" || word == "nullptr"; } PStatement statement =findStatementOf(mCurrentFile,word,getCurrentScope(),true); diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index cee4e6d6..002bab5a 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -87,6 +87,8 @@ public: PStatement findTypeDefinitionOf(const QString& fileName, const QString& aType, const PStatement& currentClass); + PStatement findTypeDef(const PStatement& statement, + const QString& fileName); bool freeze(); // Freeze/Lock (stop reparse while searching) bool freeze(const QString& serialId); // Freeze/Lock (stop reparse while searching) QStringList getClassesList(); diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 400eecd9..11d7002d 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -413,7 +413,7 @@ bool isSystemHeaderFile(const QString &fileName, const QSet &includePat return false; } -bool isKeyword(const QString &word) +bool isCppKeyword(const QString &word) { return CppKeywords.contains(word); } diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index 75fb7677..8a694778 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -255,7 +255,7 @@ QString getSystemHeaderFilename(const QString& fileName, const QStringList& incl bool isSystemHeaderFile(const QString& fileName, const QSet& includePaths); bool isHfile(const QString& filename); bool isCfile(const QString& filename); -bool isKeyword(const QString& word); +bool isCppKeyword(const QString& word); bool isScopeTypeKind(StatementKind kind); MemberOperatorType getOperatorType(const QString& phrase, int index); QStringList getOwnerExpressionAndMember(