From 4746d1b63cda0ac239665e7ac3df2d5d74e910c0 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 8 Jun 2023 17:15:55 +0800 Subject: [PATCH] - enhancement: Code completion for '->' operator on std iterators. --- NEWS.md | 1 + RedPandaIDE/parser/cppparser.cpp | 78 +++++++++++++++------ RedPandaIDE/parser/cppparser.h | 4 ++ RedPandaIDE/parser/parserutils.cpp | 6 +- RedPandaIDE/widgets/codecompletionpopup.cpp | 22 ++++++ 5 files changed, 89 insertions(+), 22 deletions(-) diff --git a/NEWS.md b/NEWS.md index a9b54a9b..8e567207 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ Red Panda C++ Version 2.23 - fix: When selection is availalbe, Ctrl+Click shouldn't jump to declaration/definition. + - enhancement: Code completion for '->' operator on std iterators. Red Panda C++ Version 2.22 diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 2c6fbec0..556318ce 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -193,6 +193,14 @@ QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QStri return doFindFirstTemplateParamOf(fileName,phrase,currentScope); } +QString CppParser::findTemplateParamOf(const QString &fileName, const QString &phrase, int index, const PStatement ¤tScope) +{ + QMutexLocker locker(&mMutex); + if (mParsing) + return ""; + return doFindTemplateParamOf(fileName,phrase,index,currentScope); +} + PStatement CppParser::findFunctionAt(const QString &fileName, int line) { QMutexLocker locker(&mMutex); @@ -4632,27 +4640,57 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, false); } else if (phraseExpression[pos] == "->") { pos++; -// qDebug()<<"pointer level"<pointerLevel; if (result->pointerLevel==0) { - PStatement typeStatement = result->effectiveTypeStatement; - if ((typeStatement) - && STLPointers.contains(typeStatement->fullName) - && result->kind == EvalStatementKind::Variable - && result->baseStatement) { - PStatement parentScope = result->baseStatement->parentScope.lock(); - QString typeName; - if (!previousResult || previousResult->definitionString.isEmpty()) - typeName = doFindFirstTemplateParamOf(fileName,result->baseStatement->type, parentScope); - else - typeName = doFindFirstTemplateParamOf(fileName,previousResult->definitionString,parentScope); -// qDebug()<<"typeName"<definitionString=typeName; - result->kind = EvalStatementKind::Variable; - } else { - return PEvalStatement(); + // iterator + if (result->typeStatement + && STLIterators.contains(result->typeStatement->command) + ) { + PStatement parentScope = result->typeStatement->parentScope.lock(); + if (STLContainers.contains(parentScope->fullName)) { + QString typeName=doFindFirstTemplateParamOf(fileName,result->templateParams, parentScope); +// qDebug()<<"typeName"<baseStatement->type<baseStatement->command; + PStatement typeStatement=doFindTypeDefinitionOf(fileName, typeName,parentScope); + if (typeStatement) { + result = doCreateEvalType(fileName,typeStatement); + result->definitionString=typeName; + result->kind = EvalStatementKind::Variable; + } else { + result = PEvalStatement(); + } + } else if (STLMaps.contains(parentScope->fullName)) { + QString typeName=doFindTemplateParamOf(fileName,result->templateParams,1,parentScope); + // qDebug()<<"typeName"<baseStatement->type<baseStatement->command; + PStatement typeStatement=doFindTypeDefinitionOf(fileName, typeName,parentScope); + if (typeStatement) { + result = doCreateEvalType(fileName,typeStatement); + result->definitionString=typeName; + result->kind = EvalStatementKind::Variable; + } else { + result = PEvalStatement(); + } + } + } else { + //smart pointer + PStatement typeStatement = result->effectiveTypeStatement; + if ((typeStatement) + && STLPointers.contains(typeStatement->fullName) + && result->kind == EvalStatementKind::Variable + && result->baseStatement) { + PStatement parentScope = result->baseStatement->parentScope.lock(); + QString typeName; + if (!previousResult || previousResult->definitionString.isEmpty()) + typeName = doFindFirstTemplateParamOf(fileName,result->baseStatement->type, parentScope); + else + typeName = doFindFirstTemplateParamOf(fileName,previousResult->definitionString,parentScope); + // qDebug()<<"typeName"<definitionString=typeName; + result->kind = EvalStatementKind::Variable; + } else { + return PEvalStatement(); + } } } } else { diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 6643d1f4..59bc4e23 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -52,6 +52,10 @@ public: QString findFirstTemplateParamOf(const QString& fileName, const QString& phrase, const PStatement& currentScope); + QString findTemplateParamOf(const QString& fileName, + const QString& phrase, + int index, + const PStatement& currentScope); PStatement findFunctionAt(const QString& fileName, int line); int findLastOperator(const QString& phrase) const; diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index ee16ce8f..1057ffa1 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -303,8 +303,10 @@ void initParser() STLPointers.insert("std::shared_ptr"); STLPointers.insert("std::weak_ptr"); //STLPointers.insert("__gnu_cxx::__normal_iterator"); - //STLPointers.insert("std::reverse_iterator"); - //STLPointers.insert("std::iterator"); +// STLPointers.insert("std::reverse_iterator"); +// STLPointers.insert("std::iterator"); +// STLPointers.insert("std::const_iterator"); +// STLPointers.insert("std::const_reverse_iterator"); AutoTypes.insert("auto"); AutoTypes.insert("auto &"); diff --git a/RedPandaIDE/widgets/codecompletionpopup.cpp b/RedPandaIDE/widgets/codecompletionpopup.cpp index 44070e5a..011f589f 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.cpp +++ b/RedPandaIDE/widgets/codecompletionpopup.cpp @@ -752,6 +752,28 @@ void CodeCompletionPopup::getCompletionFor( if (!classTypeStatement) return; + // It's a iterator + if (ownerStatement + && ownerStatement->typeStatement + && STLIterators.contains(ownerStatement->typeStatement->command) + && (memberOperator == "->" + || memberOperator == "->*") + ) { + PStatement parentScope = ownerStatement->typeStatement->parentScope.lock(); + if (STLContainers.contains(parentScope->fullName)) { + QString typeName=mParser->findFirstTemplateParamOf(fileName,ownerStatement->templateParams, parentScope); +// qDebug()<<"typeName"<baseStatement->type<baseStatement->command; + classTypeStatement=mParser->findTypeDefinitionOf(fileName, typeName,parentScope); + if (!classTypeStatement) + return; + } else if (STLMaps.contains(parentScope->fullName)) { + QString typeName=mParser->findTemplateParamOf(fileName,ownerStatement->templateParams,1,parentScope); + // qDebug()<<"typeName"<baseStatement->type<baseStatement->command; + classTypeStatement=mParser->findTypeDefinitionOf(fileName, typeName,parentScope); + if (!classTypeStatement) + return; + } + } //is a smart pointer if (STLPointers.contains(classTypeStatement->fullName) && (memberOperator == "->"