- enhancement: show compltion suggest for std::pair::first and std::pair second

This commit is contained in:
Roy Qu 2022-11-29 16:48:40 +08:00
parent 407f11aa22
commit a6d5da07a3
5 changed files with 96 additions and 22 deletions

View File

@ -13,6 +13,7 @@ Red Panda C++ Version 2.5
- enhancement: Deduce type info for "auto" in some simple cases for stl containers. - enhancement: Deduce type info for "auto" in some simple cases for stl containers.
- fix: crash when no semicolon or left brace after the keyword "namespace" - fix: crash when no semicolon or left brace after the keyword "namespace"
- fix: can't correctly show completion suggest for type with template parameters - fix: can't correctly show completion suggest for type with template parameters
- enhancement: show compltion suggest for std::pair::first and std::pair second
Red Panda C++ Version 2.4 Red Panda C++ Version 2.4

View File

@ -1082,18 +1082,29 @@ QString CppParser::getFirstTemplateParam(const PStatement& statement,
return findFirstTemplateParamOf(filename,statement->type, currentScope); return findFirstTemplateParamOf(filename,statement->type, currentScope);
} }
int CppParser::getFirstTemplateParamEnd(const QString &s, int startAt) int CppParser::getTemplateParamStart(const QString &s, int startAt, int index)
{ {
int i = startAt+1;
int count=0;
while (count<index) {
i = getTemplateParamEnd(s,i) + 2;
count++;
}
return i;
}
int CppParser::getTemplateParamEnd(const QString &s, int startAt) {
int i = startAt; int i = startAt;
int level = 0; // assume we start on top of '<' int level = 1; // pretend we start on top of '<'
while (i < s.length()) { while (i < s.length()) {
switch (s[i].unicode()) { switch (s[i].unicode()) {
case '<': case '<':
level++; level++;
break; break;
case ',': case ',':
if (level == 1) if (level == 1) {
return i; return i;
}
break; break;
case '>': case '>':
level--; level--;
@ -2005,13 +2016,20 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType)
} }
QString CppParser::doFindFirstTemplateParamOf(const QString &fileName, const QString &phrase, const PStatement &currentScope) QString CppParser::doFindFirstTemplateParamOf(const QString &fileName, const QString &phrase, const PStatement &currentScope)
{
return doFindTemplateParamOf(fileName,phrase,0,currentScope);
}
QString CppParser::doFindTemplateParamOf(const QString &fileName, const QString &phrase, int index, const PStatement &currentScope)
{ {
// Remove pointer stuff from type // Remove pointer stuff from type
QString s = phrase; // 'Type' is a keyword QString s = phrase; // 'Type' is a keyword
int i = s.indexOf('<'); int i = s.indexOf('<');
if (i>=0) { if (i>=0) {
int t=getFirstTemplateParamEnd(s,i); i=getTemplateParamStart(s,i,index);
return s.mid(i+1,t-i-1); int t=getTemplateParamEnd(s,i);
qDebug()<<index<<s<<s.mid(i,t-i)<<i<<t;
return s.mid(i,t-i);
} }
int position = s.length()-1; int position = s.length()-1;
while ((position >= 0) && (s[position] == '*' while ((position >= 0) && (s[position] == '*'
@ -3545,9 +3563,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
&& isIdentChar(mTokenizer[mIndex+1]->text.back()) && isIdentChar(mTokenizer[mIndex+1]->text.back())
&& addedVar && addedVar
&& !(addedVar->properties & StatementProperty::spFunctionPointer) && !(addedVar->properties & StatementProperty::spFunctionPointer)
&& (addedVar->type == "auto" && AutoTypes.contains(addedVar->type)) {
|| addedVar->type == "const auto"
|| addedVar->type == "const auto &")) {
QStringList phraseExpression; QStringList phraseExpression;
phraseExpression.append(mTokenizer[mIndex+1]->text); phraseExpression.append(mTokenizer[mIndex+1]->text);
int pos = 0; int pos = 0;
@ -3559,10 +3575,14 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
true); true);
if(aliasStatement && aliasStatement->effectiveTypeStatement if(aliasStatement && aliasStatement->effectiveTypeStatement
&& STLContainers.contains(aliasStatement->effectiveTypeStatement->fullName)) { && STLContainers.contains(aliasStatement->effectiveTypeStatement->fullName)) {
QString type=doFindFirstTemplateParamOf(mCurrentFile,aliasStatement->templateParams, if (STLMaps.contains(aliasStatement->effectiveTypeStatement->fullName)) {
getCurrentScope()); addedVar->type = "std::pair"+aliasStatement->templateParams;
if (!type.isEmpty()) } else {
addedVar->type = type; QString type=doFindFirstTemplateParamOf(mCurrentFile,aliasStatement->templateParams,
getCurrentScope());
if (!type.isEmpty())
addedVar->type = type;
}
} }
} }
addedVar.reset(); addedVar.reset();
@ -3661,7 +3681,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
&& isIdentifier(mTokenizer[mIndex+1]->text) && isIdentifier(mTokenizer[mIndex+1]->text)
&& addedVar && addedVar
&& !(addedVar->properties & StatementProperty::spFunctionPointer) && !(addedVar->properties & StatementProperty::spFunctionPointer)
&& addedVar->type == "auto") { && AutoTypes.contains(addedVar->type)) {
int pos = 0; int pos = 0;
int endIndex = skipAssignment(mIndex, mTokenizer.tokenCount()); int endIndex = skipAssignment(mIndex, mTokenizer.tokenCount());
@ -3716,7 +3736,7 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
&& isIdentifier(mTokenizer[mIndex+1]->text) && isIdentifier(mTokenizer[mIndex+1]->text)
&& addedVar && addedVar
&& !(addedVar->properties & StatementProperty::spFunctionPointer) && !(addedVar->properties & StatementProperty::spFunctionPointer)
&& addedVar->type == "auto") { && AutoTypes.contains(addedVar->type)) {
int pos = 0; int pos = 0;
int endIndex = mTokenizer[mIndex]->matchIndex; int endIndex = mTokenizer[mIndex]->matchIndex;
QStringList phraseExpression; QStringList phraseExpression;
@ -4503,7 +4523,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
break; break;
case StatementKind::skVariable: case StatementKind::skVariable:
case StatementKind::skParameter: case StatementKind::skParameter:
result = doCreateEvalVariable(fileName,statement); result = doCreateEvalVariable(fileName,statement, previousResult?previousResult->templateParams:"",scope);
break; break;
case StatementKind::skEnumType: case StatementKind::skEnumType:
case StatementKind::skClass: case StatementKind::skClass:
@ -4626,7 +4646,11 @@ PEvalStatement CppParser::doCreateEvalType(const QString &primitiveType)
PStatement()); PStatement());
} }
PEvalStatement CppParser::doCreateEvalVariable(const QString &fileName, PStatement varStatement) PEvalStatement CppParser::doCreateEvalVariable(
const QString &fileName,
const PStatement& varStatement,
const QString& baseTemplateParams,
const PStatement& scope)
{ {
if (!varStatement) if (!varStatement)
return PEvalStatement(); return PEvalStatement();
@ -4634,7 +4658,29 @@ PEvalStatement CppParser::doCreateEvalVariable(const QString &fileName, PStateme
int pointerLevel=0; int pointerLevel=0;
QString templateParams; QString templateParams;
PStatement typeStatement; PStatement typeStatement;
PStatement effetiveTypeStatement = doParseEvalTypeInfo( PStatement effectiveTypeStatement;
//todo: ugly implementation for std::pair
if (varStatement->fullName == "std::pair::first") {
effectiveTypeStatement = doParseEvalTypeInfo(
fileName,
scope,
doFindFirstTemplateParamOf(fileName,baseTemplateParams,scope),
baseType,
typeStatement,
pointerLevel,
templateParams);
} else if (varStatement->fullName == "std::pair::second") {
effectiveTypeStatement = doParseEvalTypeInfo(
fileName,
scope,
doFindTemplateParamOf(fileName,baseTemplateParams,1,scope),
baseType,
typeStatement,
pointerLevel,
templateParams);
} else {
effectiveTypeStatement = doParseEvalTypeInfo(
fileName, fileName,
varStatement->parentScope.lock(), varStatement->parentScope.lock(),
varStatement->type+varStatement->args, varStatement->type+varStatement->args,
@ -4642,19 +4688,22 @@ PEvalStatement CppParser::doCreateEvalVariable(const QString &fileName, PStateme
typeStatement, typeStatement,
pointerLevel, pointerLevel,
templateParams); templateParams);
}
// qDebug()<<"parse ..."<<baseType<<pointerLevel; // qDebug()<<"parse ..."<<baseType<<pointerLevel;
return std::make_shared<EvalStatement>( return std::make_shared<EvalStatement>(
baseType, baseType,
EvalStatementKind::Variable, EvalStatementKind::Variable,
varStatement, varStatement,
typeStatement, typeStatement,
effetiveTypeStatement, effectiveTypeStatement,
pointerLevel, pointerLevel,
templateParams templateParams
); );
} }
PEvalStatement CppParser::doCreateEvalFunction(const QString &fileName, PStatement funcStatement) PEvalStatement CppParser::doCreateEvalFunction(
const QString &fileName,
const PStatement& funcStatement)
{ {
if (!funcStatement) if (!funcStatement)
return PEvalStatement(); return PEvalStatement();

View File

@ -228,6 +228,10 @@ private:
QString doFindFirstTemplateParamOf(const QString& fileName, QString doFindFirstTemplateParamOf(const QString& fileName,
const QString& phrase, const QString& phrase,
const PStatement& currentScope); const PStatement& currentScope);
QString doFindTemplateParamOf(const QString& fileName,
const QString& phrase,
int index,
const PStatement& currentScope);
void fillListOfFunctions(const QString& fileName, int line, void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement, const PStatement& statement,
@ -322,8 +326,12 @@ private:
PEvalStatement doCreateEvalType(const QString& fileName,const PStatement& typeStatement); PEvalStatement doCreateEvalType(const QString& fileName,const PStatement& typeStatement);
PEvalStatement doCreateEvalType(const QString& primitiveType); PEvalStatement doCreateEvalType(const QString& primitiveType);
PEvalStatement doCreateEvalVariable(const QString& fileName, PStatement varStatement); PEvalStatement doCreateEvalVariable(
PEvalStatement doCreateEvalFunction(const QString& fileName, PStatement funcStatement); const QString& fileName,
const PStatement& varStatement,
const QString& baseTemplateParams,
const PStatement& scope);
PEvalStatement doCreateEvalFunction(const QString& fileName, const PStatement& funcStatement);
PEvalStatement doCreateEvalLiteral(const QString& type); PEvalStatement doCreateEvalLiteral(const QString& type);
void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol); void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol);
@ -404,7 +412,8 @@ private:
PStatement getCurrentScope(); // gets last item from last level PStatement getCurrentScope(); // gets last item from last level
QString getFirstTemplateParam(const PStatement& statement, const QString& filename, QString getFirstTemplateParam(const PStatement& statement, const QString& filename,
const QString& phrase, const PStatement& currentScope); const QString& phrase, const PStatement& currentScope);
int getFirstTemplateParamEnd(const QString& s, int startAt); int getTemplateParamStart(const QString& s, int startAt, int index);
int getTemplateParamEnd(const QString& s, int startAt);
void getFullNamespace( void getFullNamespace(
const QString& phrase, const QString& phrase,

View File

@ -31,10 +31,12 @@ QSet<QString> CppTypeKeywords;
QSet<QString> CKeywords; QSet<QString> CKeywords;
QSet<QString> STLPointers; QSet<QString> STLPointers;
QSet<QString> STLContainers; QSet<QString> STLContainers;
QSet<QString> STLMaps;
QSet<QString> STLElementMethods; QSet<QString> STLElementMethods;
QSet<QString> STLIterators; QSet<QString> STLIterators;
QSet<QString> MemberOperators; QSet<QString> MemberOperators;
QSet<QString> IOManipulators; QSet<QString> IOManipulators;
QSet<QString> AutoTypes;
Q_GLOBAL_STATIC(QSet<QString>,CppHeaderExts) Q_GLOBAL_STATIC(QSet<QString>,CppHeaderExts)
Q_GLOBAL_STATIC(QSet<QString>,CppSourceExts) Q_GLOBAL_STATIC(QSet<QString>,CppSourceExts)
@ -270,6 +272,12 @@ void initParser()
STLContainers.insert("std::span"); STLContainers.insert("std::span");
STLMaps.insert("std::map");
STLMaps.insert("std::multilist");
STLMaps.insert("std::multimap");
STLMaps.insert("std::unordered_map");
STLMaps.insert("std::unordered_multimap");
//STL element access methods //STL element access methods
STLElementMethods.insert("at"); STLElementMethods.insert("at");
STLElementMethods.insert("back"); STLElementMethods.insert("back");
@ -293,6 +301,11 @@ void initParser()
//STLPointers.insert("std::reverse_iterator"); //STLPointers.insert("std::reverse_iterator");
//STLPointers.insert("std::iterator"); //STLPointers.insert("std::iterator");
AutoTypes.insert("auto");
AutoTypes.insert("auto &");
AutoTypes.insert("const auto");
AutoTypes.insert("const auto &");
//C/CPP preprocessor directives //C/CPP preprocessor directives
CppDirectives.append("#include"); CppDirectives.append("#include");
CppDirectives.append("#if"); CppDirectives.append("#if");

View File

@ -303,10 +303,12 @@ extern QSet<QString> CKeywords;
extern QSet<QString> CppTypeKeywords; extern QSet<QString> CppTypeKeywords;
extern QSet<QString> STLPointers; extern QSet<QString> STLPointers;
extern QSet<QString> STLContainers; extern QSet<QString> STLContainers;
extern QSet<QString> STLMaps;
extern QSet<QString> STLElementMethods; extern QSet<QString> STLElementMethods;
extern QSet<QString> STLIterators; extern QSet<QString> STLIterators;
extern QSet<QString> MemberOperators; extern QSet<QString> MemberOperators;
extern QSet<QString> IOManipulators; extern QSet<QString> IOManipulators;
extern QSet<QString> AutoTypes;
void initParser(); void initParser();