- enhancement: Show code completion suggestion after "typedef" and "const".

This commit is contained in:
Roy Qu 2023-07-03 09:36:27 +08:00
parent 9e5fd90196
commit b571e5f535
6 changed files with 95 additions and 5 deletions

View File

@ -24,6 +24,7 @@ Red Panda C++ Version 2.23
- improvement: Correctly eppands macros when real param string contains '(' or ')'.
- enhancement: add "OI Wiki" and "turtle graphics tutorial" in help menu for zh_CN locale.
- fix: Replace panel should be hidden after finding occurrencies.
- enhancement: Show code completion suggestion after "typedef" and "const".
Red Panda C++ Version 2.22

View File

@ -857,7 +857,12 @@ void Editor::keyPressEvent(QKeyEvent *event)
} else {
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
if (mParser && !lastWord.isEmpty()) {
if (lastWord == "using") {
if (lastWord == "typedef" || lastWord == "const") {
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::Types);
handled=true;
return;
} else if (lastWord == "using") {
processCommand(QSynedit::EditCommand::Char,ch,nullptr);
showCompletion(lastWord,false, CodeCompletionType::ComplexKeyword);
handled=true;

View File

@ -589,6 +589,15 @@ PStatement CppParser::findAliasedStatement(const PStatement &statement)
return PStatement();
return doFindAliasedStatement(statement);
}
QList<PStatement> CppParser::listTypeStatements(const QString &fileName, int line)
{
QMutexLocker locker(&mMutex);
if (mParsing)
return QList<PStatement>();
return doListTypeStatements(fileName,line);
}
PStatement CppParser::doFindAliasedStatement(const PStatement &statement) const
{
if (!statement)
@ -612,6 +621,36 @@ PStatement CppParser::doFindAliasedStatement(const PStatement &statement) const
return PStatement();
}
QList<PStatement> CppParser::doListTypeStatements(const QString &fileName, int line) const
{
QList<PStatement> result;
QSet<QString> usedNamespaces;
PStatement scopeStatement = doFindScopeStatement(fileName,line);
while (true) {
const StatementMap& statementMap = mStatementList.childrenStatements(scopeStatement);
foreach (const PStatement statement, statementMap.values()) {
if (isTypeStatement(statement->kind))
result.append(statement);
}
if (!scopeStatement)
break;
usedNamespaces = usedNamespaces.unite(scopeStatement->usingList);
scopeStatement=scopeStatement->parentScope.lock();
}
usedNamespaces = usedNamespaces.unite(internalGetFileUsings(fileName));
foreach(const QString& ns, usedNamespaces) {
PStatementList namespaceStatementsList=doFindNamespace(ns);
foreach (const PStatement& namespaceStatement,*namespaceStatementsList) {
const StatementMap& statementMap = mStatementList.childrenStatements(namespaceStatement);
foreach (const PStatement statement, statementMap.values()) {
if (isTypeStatement(statement->kind))
result.append(statement);
}
}
}
return result;
}
PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope) const
{
PStatement scopeStatement = startScope;

View File

@ -77,6 +77,8 @@ public:
int line);
PStatement findAliasedStatement(const PStatement& statement);
QList<PStatement> listTypeStatements(const QString& fileName,int line);
/**
* @brief evaluate the expression
* @param fileName
@ -251,6 +253,8 @@ private:
int line) const;
PStatement doFindAliasedStatement(const PStatement& statement) const;
QList<PStatement> doListTypeStatements(const QString& fileName,int line) const;
PStatement doFindTypeDefinitionOf(const QString& fileName,
const QString& aType,
const PStatement& currentClass) const;

View File

@ -94,7 +94,11 @@ void CodeCompletionPopup::prepareSearch(
mMemberOperator = memberOperator;
switch(type) {
case CodeCompletionType::ComplexKeyword:
getCompletionListForTypeKeywordComplex(preWord);
getCompletionListForComplexKeyword(preWord);
break;
case CodeCompletionType::Types:
mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionListForTypes(preWord,filename,line);
break;
case CodeCompletionType::FunctionWithoutDefinition:
mIncludedFiles = mParser->getFileIncludes(filename);
@ -892,7 +896,7 @@ void CodeCompletionPopup::getCompletionForFunctionWithoutDefinition(const QStrin
});
if (memberOperator.isEmpty()) {
getCompletionListForTypeKeywordComplex(preWord);
getCompletionListForComplexKeyword(preWord);
PStatement scopeStatement = mCurrentScope;
//add members of current scope that not added before
while (scopeStatement && scopeStatement->kind!=StatementKind::skNamespace
@ -960,7 +964,7 @@ void CodeCompletionPopup::getCompletionForFunctionWithoutDefinition(const QStrin
}
}
void CodeCompletionPopup::getCompletionListForTypeKeywordComplex(const QString &preWord)
void CodeCompletionPopup::getCompletionListForComplexKeyword(const QString &preWord)
{
mFullCompletionStatementList.clear();
if (preWord == "long") {
@ -1012,6 +1016,39 @@ void CodeCompletionPopup::getCompletionListForNamespaces(const QString &/*preWor
}
}
void CodeCompletionPopup::getCompletionListForTypes(const QString &preWord, const QString &fileName, int line)
{
if (preWord=="typedef") {
addKeyword("const");
addKeyword("struct");
addKeyword("class");
}
if (mShowKeywords) {
//add keywords
foreach (const QString& keyword,CppTypeKeywords) {
addKeyword(keyword);
}
}
if (!mParser->enabled())
return;
if (!mParser->freeze())
return;
{
auto action = finally([this]{
mParser->unFreeze();
});
QList<PStatement> statements = mParser->listTypeStatements(fileName,line);
foreach(const PStatement& statement, statements) {
if (isIncluded(statement->fileName)
|| isIncluded(statement->definitionFileName)) {
addStatement(statement,fileName,line);
}
}
}
}
void CodeCompletionPopup::addKeyword(const QString &keyword)
{
PStatement statement = std::make_shared<Statement>();

View File

@ -42,6 +42,7 @@ enum class CodeCompletionType {
ComplexKeyword,
FunctionWithoutDefinition,
Namespaces,
Types,
KeywordsOnly
};
@ -151,10 +152,13 @@ private:
const QString& fileName,
int line);
void getCompletionListForTypeKeywordComplex(const QString& preWord);
void getCompletionListForComplexKeyword(const QString& preWord);
void getCompletionListForNamespaces(const QString &preWord,
const QString& fileName,
int line);
void getCompletionListForTypes(const QString &preWord,
const QString& fileName,
int line);
void addKeyword(const QString& keyword);
bool isIncluded(const QString& fileName);
private: