- enhancement: Don't show operator overloading functions in the complete suggestions

- enhancement: Correctly hanlde operator overloading functions like "operator ClassA"
This commit is contained in:
Roy Qu 2023-03-10 20:13:52 +08:00
parent f2162e97df
commit fec78d0045
5 changed files with 66 additions and 42 deletions

View File

@ -19,7 +19,10 @@ Red Panda C++ Version 2.17
- enhancement: If no selection, Ctrl+C (Copy) auto selects the current line and put the cursor to the beginning. - enhancement: If no selection, Ctrl+C (Copy) auto selects the current line and put the cursor to the beginning.
- fix: Chinese characters in the source code is not correctly displayed in the CPU info window. - fix: Chinese characters in the source code is not correctly displayed in the CPU info window.
- fix: Can't undo & save after copy by drag with mouse. - fix: Can't undo & save after copy by drag with mouse.
- fix: '::' is not correctly handle when skip to next ':' in the parser. - fix: '::' is not correctly handled when skip to next ':' in the parser.
- fix: '::' is not correctly handled when parsing class definitions.
- enhancement: Don't show operator overloading functions in the complete suggestions
- enhancement: Correctly hanlde operator overloading functions like "operator ClassA"
Red Panda C++ Version 2.16 Red Panda C++ Version 2.16

View File

@ -1377,8 +1377,8 @@ void CppParser::setInheritance(int index, const PStatement& classStatement, bool
//skip to matching ')' //skip to matching ')'
index=mTokenizer[index]->matchIndex; index=mTokenizer[index]->matchIndex;
} else if (inheritScopeType == StatementClassScope::None) { } else if (inheritScopeType == StatementClassScope::None) {
if (currentText.front()!=',' if (currentText !=','
&& currentText.front()!=':') { && currentText!=':') {
QString basename = currentText; QString basename = currentText;
//remove template staff //remove template staff
if (basename.endsWith('>')) { if (basename.endsWith('>')) {
@ -1728,8 +1728,17 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
currentText=mTokenizer[mIndex+1]->text; currentText=mTokenizer[mIndex+1]->text;
mIndex+=2; mIndex+=2;
} }
} else } else {
if (currentText=="operator") {
handleOperatorOverloading("",
"",
mIndex,
false,
false);
return;
}
mIndex++; mIndex++;
}
//next token must be */&/word/(/{ //next token must be */&/word/(/{
if (mTokenizer[mIndex]->text=='(') { if (mTokenizer[mIndex]->text=='(') {
int indexAfterParentheis=mTokenizer[mIndex]->matchIndex+1; int indexAfterParentheis=mTokenizer[mIndex]->matchIndex+1;
@ -1742,7 +1751,7 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
mIndex=indexAfterParentheis; mIndex=indexAfterParentheis;
handleMethod(StatementKind::skFunction,"", handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1), mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false); indexAfterParentheis,false,false,true);
} else { } else {
handleVar(currentText,false,false); handleVar(currentText,false,false);
} }
@ -1751,7 +1760,7 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
// operator overloading // operator overloading
handleOperatorOverloading( handleOperatorOverloading(
"", "",
currentText, "",
mIndex, mIndex,
false, false,
false); false);
@ -2539,6 +2548,9 @@ void CppParser::handleOperatorOverloading(const QString &sType, const QString &p
} else { } else {
op=mTokenizer[index]->text; op=mTokenizer[index]->text;
index++; index++;
while (index<mTokenizer.tokenCount()
&& mTokenizer[index]->text != "(")
index++;
} }
while (index<mTokenizer.tokenCount() while (index<mTokenizer.tokenCount()
&& mTokenizer[index]->text == ")") && mTokenizer[index]->text == ")")
@ -2548,15 +2560,17 @@ void CppParser::handleOperatorOverloading(const QString &sType, const QString &p
mIndex=index; mIndex=index;
return; return;
} }
Q_ASSERT(!op.isEmpty());
handleMethod(StatementKind::skFunction, handleMethod(StatementKind::skFunction,
sType, sType,
prefix+"operator"+op, prefix+"operator"+(isIdentChar(op.front())?op+" ":op),
index, index,
isStatic, isStatic,
isFriend); isFriend,
true);
} }
void CppParser::handleMethod(StatementKind functionKind,const QString &sType, const QString &sName, int argStart, bool isStatic, bool isFriend) void CppParser::handleMethod(StatementKind functionKind,const QString &sType, const QString &sName, int argStart, bool isStatic, bool isFriend,bool isOperatorOverload)
{ {
bool isValid = true; bool isValid = true;
bool isDeclaration = false; // assume it's not a prototype bool isDeclaration = false; // assume it's not a prototype
@ -2618,7 +2632,7 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
// Use the class the function belongs to as the parent ID if the function is declared outside of the class body // Use the class the function belongs to as the parent ID if the function is declared outside of the class body
QString scopelessName; QString scopelessName;
QString parentClassName; QString parentClassName;
if (splitLastMember(sName,scopelessName,parentClassName)) { if (!isOperatorOverload && splitLastMember(sName,scopelessName,parentClassName)) {
// Provide Bar instead of Foo::Bar // Provide Bar instead of Foo::Bar
scopeStatement = getIncompleteClass(parentClassName,getCurrentScope()); scopeStatement = getIncompleteClass(parentClassName,getCurrentScope());
@ -2647,7 +2661,8 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
getScope(), getScope(),
mClassScope, mClassScope,
StatementProperty::spHasDefinition StatementProperty::spHasDefinition
| (isStatic?StatementProperty::spStatic:StatementProperty::spNone)); | (isStatic?StatementProperty::spStatic:StatementProperty::spNone)
| (isOperatorOverload?StatementProperty::spOperatorOverloading:StatementProperty::spNone));
scanMethodArgs(functionStatement, argStart); scanMethodArgs(functionStatement, argStart);
// add variable this to the class function // add variable this to the class function
if (scopeStatement && scopeStatement->kind == StatementKind::skClass && if (scopeStatement && scopeStatement->kind == StatementKind::skClass &&
@ -2665,7 +2680,8 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
StatementKind::skVariable, StatementKind::skVariable,
StatementScope::Local, StatementScope::Local,
StatementClassScope::None, StatementClassScope::None,
StatementProperty::spHasDefinition); StatementProperty::spHasDefinition
| (isOperatorOverload?StatementProperty::spOperatorOverloading:StatementProperty::spNone));
} }
// add "__func__ variable" // add "__func__ variable"
@ -2681,7 +2697,8 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
StatementKind::skVariable, StatementKind::skVariable,
StatementScope::Local, StatementScope::Local,
StatementClassScope::None, StatementClassScope::None,
StatementProperty::spHasDefinition); StatementProperty::spHasDefinition
| (isOperatorOverload?StatementProperty::spOperatorOverloading:StatementProperty::spNone));
} else { } else {
functionStatement = addStatement( functionStatement = addStatement(
@ -2697,7 +2714,8 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
functionKind, functionKind,
getScope(), getScope(),
mClassScope, mClassScope,
(isStatic?StatementProperty::spStatic:StatementProperty::spNone)); (isStatic?StatementProperty::spStatic:StatementProperty::spNone)
| (isOperatorOverload?StatementProperty::spOperatorOverloading:StatementProperty::spNone));
} }
} }
@ -3208,17 +3226,17 @@ void CppParser::handleStructs(bool isTypedef)
} else { } else {
PStatement firstSynonym; PStatement firstSynonym;
// Add class/struct name BEFORE opening brace // Add class/struct name BEFORE opening brace
if (mTokenizer[mIndex]->text.front() != '{') { if (mTokenizer[mIndex]->text != "{") {
while(mIndex < mTokenizer.tokenCount()) { while(mIndex < mTokenizer.tokenCount()) {
if (mTokenizer[mIndex]->text.front() == ':' if (mTokenizer[mIndex]->text == ":"
|| mTokenizer[mIndex]->text.front() == '{' || mTokenizer[mIndex]->text == "{"
|| mTokenizer[mIndex]->text.front() == ';') { || mTokenizer[mIndex]->text == ";") {
break; break;
} else if ((mIndex + 1 < mTokenizer.tokenCount()) } else if ((mIndex + 1 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 1]->text.front() == ',' && (mTokenizer[mIndex + 1]->text == ","
|| mTokenizer[mIndex + 1]->text.front() == ';' || mTokenizer[mIndex + 1]->text == ";"
|| mTokenizer[mIndex + 1]->text.front() == '{' || mTokenizer[mIndex + 1]->text == "{"
|| mTokenizer[mIndex + 1]->text.front() == ':')) { || mTokenizer[mIndex + 1]->text == ":")) {
QString command = mTokenizer[mIndex]->text; QString command = mTokenizer[mIndex]->text;
PStatement scopeStatement=getCurrentScope(); PStatement scopeStatement=getCurrentScope();
@ -3250,8 +3268,8 @@ void CppParser::handleStructs(bool isTypedef)
break; break;
} else if ((mIndex + 2 < mTokenizer.tokenCount()) } else if ((mIndex + 2 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 1]->text == "final") && (mTokenizer[mIndex + 1]->text == "final")
&& (mTokenizer[mIndex + 2]->text.front()==',' && (mTokenizer[mIndex + 2]->text==","
|| mTokenizer[mIndex + 2]->text.front()==':' || mTokenizer[mIndex + 2]->text==":"
|| isblockChar(mTokenizer[mIndex + 2]->text.front()))) { || isblockChar(mTokenizer[mIndex + 2]->text.front()))) {
QString command = mTokenizer[mIndex]->text; QString command = mTokenizer[mIndex]->text;
if (!command.isEmpty()) { if (!command.isEmpty()) {
@ -3279,7 +3297,7 @@ void CppParser::handleStructs(bool isTypedef)
} }
// Walk to opening brace if we encountered inheritance statements // Walk to opening brace if we encountered inheritance statements
if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() == ':')) { if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text == ":")) {
if (firstSynonym) if (firstSynonym)
setInheritance(mIndex, firstSynonym, isStruct); // set the _InheritanceList value setInheritance(mIndex, firstSynonym, isStruct); // set the _InheritanceList value
mIndex=indexOfNextLeftBrace(mIndex); mIndex=indexOfNextLeftBrace(mIndex);
@ -3416,7 +3434,7 @@ void CppParser::handleStructs(bool isTypedef)
addSoloScopeLevel(firstSynonym,startLine); addSoloScopeLevel(firstSynonym,startLine);
// Step over { // Step over {
if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() == '{')) if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text == "{"))
mIndex++; mIndex++;
} }
} }
@ -3817,7 +3835,7 @@ void CppParser::internalParse(const QString &fileName)
QStringList preprocessResult = mPreprocessor.result(); QStringList preprocessResult = mPreprocessor.result();
#ifdef QT_DEBUG #ifdef QT_DEBUG
stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName))); // stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
// mPreprocessor.dumpDefinesTo("r:\\defines.txt"); // mPreprocessor.dumpDefinesTo("r:\\defines.txt");
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt"); // mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
#endif #endif
@ -3831,7 +3849,7 @@ void CppParser::internalParse(const QString &fileName)
if (mTokenizer.tokenCount() == 0) if (mTokenizer.tokenCount() == 0)
return; return;
#ifdef QT_DEBUG #ifdef QT_DEBUG
mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); // mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
#endif #endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
mLastIndex = -1; mLastIndex = -1;
@ -3842,8 +3860,8 @@ void CppParser::internalParse(const QString &fileName)
break; break;
} }
#ifdef QT_DEBUG #ifdef QT_DEBUG
mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName))); // mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName))); // mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
#endif #endif
//reduce memory usage //reduce memory usage
internalClear(); internalClear();

View File

@ -455,7 +455,8 @@ private:
const QString& sName, const QString& sName,
int argStart, int argStart,
bool isStatic, bool isStatic,
bool isFriend); bool isFriend,
bool isOperatorOverload=false);
void handleNamespace(KeywordType skipType); void handleNamespace(KeywordType skipType);
void handleOtherTypedefs(); void handleOtherTypedefs();
void handlePreprocessor(); void handlePreprocessor();

View File

@ -141,16 +141,17 @@ struct StatementMatchPosition{
}; };
enum StatementProperty { enum StatementProperty {
spNone = 0x0, spNone = 0x0,
spStatic = 0x0001, spStatic = 0x0001,
spHasDefinition = 0x0002, spHasDefinition = 0x0002,
spInProject = 0x0004, spInProject = 0x0004,
spInSystemHeader = 0x0008, spInSystemHeader = 0x0008,
spInherited = 0x0010, spInherited = 0x0010,
spVirtual = 0x0020, spVirtual = 0x0020,
spOverride = 0x0040, spOverride = 0x0040,
spConstexpr = 0x0080, spConstexpr = 0x0080,
spFunctionPointer = 0x0100 spFunctionPointer = 0x0100,
spOperatorOverloading = 0x0200
}; };
Q_DECLARE_FLAGS(StatementProperties, StatementProperty) Q_DECLARE_FLAGS(StatementProperties, StatementProperty)

View File

@ -252,7 +252,8 @@ void CodeCompletionPopup::addStatement(const PStatement& statement, const QStrin
return; return;
if (statement->kind == StatementKind::skConstructor if (statement->kind == StatementKind::skConstructor
|| statement->kind == StatementKind::skDestructor || statement->kind == StatementKind::skDestructor
|| statement->kind == StatementKind::skBlock) || statement->kind == StatementKind::skBlock
|| statement->properties.testFlag(StatementProperty::spOperatorOverloading))
return; return;
if ((line!=-1) if ((line!=-1)
&& (line < statement->line) && (line < statement->line)