- fix: can't correctly show completion suggest for type with template parameters

- enhancement: correctly evaluate auto variable of stl container iterator.
This commit is contained in:
Roy Qu 2022-11-29 12:06:29 +08:00
parent 3a1bc97ca5
commit 0d0332aa7d
6 changed files with 118 additions and 52 deletions

View File

@ -10,8 +10,9 @@ Red Panda C++ Version 2.5
- change: Default value of option "Auto clear symbols in hidden editors" is ON if number of CPU cores > 8 and "Editors share one code analyzer" is on - change: Default value of option "Auto clear symbols in hidden editors" is ON if number of CPU cores > 8 and "Editors share one code analyzer" is on
- enhancement: show completion suggest for "namespace" after "using" - enhancement: show completion suggest for "namespace" after "using"
- fix: MinGW-w64 gcc displayed as "MinGW GCC" - fix: MinGW-w64 gcc displayed as "MinGW GCC"
- enhancement: Deduce type info for "auto" in some simple cases. - 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
Red Panda C++ Version 2.4 Red Panda C++ Version 2.4

View File

@ -2141,7 +2141,7 @@ QStringList Editor::getExpressionAtPosition(
case LastSymbolType::MatchingAngleQuotation: case LastSymbolType::MatchingAngleQuotation:
if (token=="<") { if (token=="<") {
if (symbolMatchingLevel==0) { if (symbolMatchingLevel==0) {
lastSymbolType=LastSymbolType::MatchingAngleQuotation; lastSymbolType=LastSymbolType::AngleQuotationMatched;
} else { } else {
symbolMatchingLevel--; symbolMatchingLevel--;
} }

View File

@ -3685,9 +3685,11 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
PEvalStatement(), PEvalStatement(),
true); true);
if(aliasStatement) { if(aliasStatement) {
if (aliasStatement->effectiveTypeStatement) if (aliasStatement->effectiveTypeStatement) {
addedVar->type = aliasStatement->effectiveTypeStatement->fullName; addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
else if (!addedVar->type.endsWith(">"))
addedVar->type += aliasStatement->templateParams;
} else
addedVar->type = aliasStatement->baseType; addedVar->type = aliasStatement->baseType;
if (aliasStatement->pointerLevel>0) if (aliasStatement->pointerLevel>0)
addedVar->type += QString(aliasStatement->pointerLevel,'*'); addedVar->type += QString(aliasStatement->pointerLevel,'*');
@ -3728,9 +3730,11 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
PEvalStatement(), PEvalStatement(),
true); true);
if(aliasStatement && aliasStatement->effectiveTypeStatement) { if(aliasStatement && aliasStatement->effectiveTypeStatement) {
if (aliasStatement->effectiveTypeStatement) if (aliasStatement->effectiveTypeStatement) {
addedVar->type = aliasStatement->effectiveTypeStatement->fullName; addedVar->type = aliasStatement->effectiveTypeStatement->fullName;
else if (!addedVar->type.endsWith(">"))
addedVar->type += aliasStatement->templateParams;
} else
addedVar->type = aliasStatement->baseType; addedVar->type = aliasStatement->baseType;
if (aliasStatement->pointerLevel>0) if (aliasStatement->pointerLevel>0)
addedVar->type += QString(aliasStatement->pointerLevel,'*'); addedVar->type += QString(aliasStatement->pointerLevel,'*');
@ -4102,7 +4106,23 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName,
freeScoped); freeScoped);
if (result) { if (result) {
//todo: STL container; //todo: STL container;
if (result->pointerLevel==0) { if (result->pointerLevel==0) {
//STL smart pointers
if (result->typeStatement
&& STLIterators.contains(result->typeStatement->command)
) {
PStatement parentScope = result->typeStatement->parentScope.lock();
if (STLContainers.contains(parentScope->fullName)) {
QString typeName=findFirstTemplateParamOf(fileName,result->templateParams, parentScope);
// qDebug()<<"typeName"<<typeName<<lastResult->baseStatement->type<<lastResult->baseStatement->command;
PStatement typeStatement=findTypeDefinitionOf(fileName, typeName,parentScope);
if (typeStatement) {
result = doCreateEvalType(fileName,typeStatement);
result->kind = EvalStatementKind::Variable;
}
}
} else {
PStatement typeStatement = result->effectiveTypeStatement; PStatement typeStatement = result->effectiveTypeStatement;
if ((typeStatement) if ((typeStatement)
&& STLPointers.contains(typeStatement->fullName) && STLPointers.contains(typeStatement->fullName)
@ -4110,13 +4130,14 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName,
&& result->baseStatement) { && result->baseStatement) {
PStatement parentScope = result->baseStatement->parentScope.lock(); PStatement parentScope = result->baseStatement->parentScope.lock();
QString typeName=findFirstTemplateParamOf(fileName,result->baseStatement->type, parentScope); QString typeName=findFirstTemplateParamOf(fileName,result->baseStatement->type, parentScope);
// qDebug()<<"typeName"<<typeName; // qDebug()<<"typeName"<<typeName;
typeStatement=findTypeDefinitionOf(fileName, typeName,parentScope); typeStatement=findTypeDefinitionOf(fileName, typeName,parentScope);
if (typeStatement) { if (typeStatement) {
result = doCreateEvalType(fileName,typeStatement); result = doCreateEvalType(fileName,typeStatement);
result->kind = EvalStatementKind::Variable; result->kind = EvalStatementKind::Variable;
} }
} }
}
} else } else
result->pointerLevel--; result->pointerLevel--;
} }
@ -4443,18 +4464,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
if (!previousResult) { if (!previousResult) {
statement = findStatementInScope(phraseExpression[pos],PStatement()); statement = findStatementInScope(phraseExpression[pos],PStatement());
} else { } else {
// if (previousResult->effectiveTypeStatement) {
// qDebug()<<phraseExpression[pos]<<previousResult->effectiveTypeStatement->fullName;
// } else {
// qDebug()<<phraseExpression[pos]<<"no type";
// }
statement = findStatementInScope(phraseExpression[pos],previousResult->effectiveTypeStatement); statement = findStatementInScope(phraseExpression[pos],previousResult->effectiveTypeStatement);
// if (!statement) {
// qDebug()<<"not found!";
// } else {
// qDebug()<<statement->fullName;
// qDebug()<<statement->kind;
// }
} }
} }
pos++; pos++;
@ -4488,6 +4498,17 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
default: default:
result = PEvalStatement(); result = PEvalStatement();
} }
if (result
&& result->typeStatement
&& STLIterators.contains(result->typeStatement->command)
&& previousResult) {
PStatement parentStatement = result->typeStatement->parentScope.lock();
if (parentStatement
&& STLContainers.contains(parentStatement->fullName)) {
// result->baseType = parentStatement->fullName+previousResult->templateParams+result->typeStatement->command;
result->templateParams = previousResult->templateParams;
}
}
} }
} else if (isIntegerLiteral(phraseExpression[pos])) { } else if (isIntegerLiteral(phraseExpression[pos])) {
result = doCreateEvalLiteral("int"); result = doCreateEvalLiteral("int");
@ -4525,6 +4546,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
// if (!result) { // if (!result) {
// qDebug()<<"not found !!!!"; // qDebug()<<"not found !!!!";
// } // }
return result; return result;
} }
@ -4536,6 +4558,7 @@ PEvalStatement CppParser::doCreateEvalNamespace(const PStatement &namespaceState
namespaceStatement->fullName, namespaceStatement->fullName,
EvalStatementKind::Namespace, EvalStatementKind::Namespace,
PStatement(), PStatement(),
namespaceStatement,
namespaceStatement); namespaceStatement);
} }
@ -4546,24 +4569,31 @@ PEvalStatement CppParser::doCreateEvalType(const QString& fileName,const PStatem
if (typeStatement->kind == StatementKind::skTypedef) { if (typeStatement->kind == StatementKind::skTypedef) {
QString baseType; QString baseType;
int pointerLevel=0; int pointerLevel=0;
PStatement statement = doParseEvalTypeInfo( QString templateParams;
PStatement tempStatement;
PStatement effetiveTypeStatement = doParseEvalTypeInfo(
fileName, fileName,
typeStatement->parentScope.lock(), typeStatement->parentScope.lock(),
typeStatement->type + typeStatement->args, typeStatement->type + typeStatement->args,
baseType, baseType,
pointerLevel); tempStatement,
pointerLevel,
templateParams);
return std::make_shared<EvalStatement>( return std::make_shared<EvalStatement>(
baseType, baseType,
EvalStatementKind::Type, EvalStatementKind::Type,
PStatement(), PStatement(),
typeStatement, typeStatement,
pointerLevel effetiveTypeStatement,
pointerLevel,
templateParams
); );
} else { } else {
return std::make_shared<EvalStatement>( return std::make_shared<EvalStatement>(
typeStatement->fullName, typeStatement->fullName,
EvalStatementKind::Type, EvalStatementKind::Type,
PStatement(), PStatement(),
typeStatement,
typeStatement); typeStatement);
} }
} }
@ -4574,6 +4604,7 @@ PEvalStatement CppParser::doCreateEvalType(const QString &primitiveType)
primitiveType, primitiveType,
EvalStatementKind::Type, EvalStatementKind::Type,
PStatement(), PStatement(),
PStatement(),
PStatement()); PStatement());
} }
@ -4583,19 +4614,25 @@ PEvalStatement CppParser::doCreateEvalVariable(const QString &fileName, PStateme
return PEvalStatement(); return PEvalStatement();
QString baseType; QString baseType;
int pointerLevel=0; int pointerLevel=0;
PStatement typeStatement = doParseEvalTypeInfo( QString templateParams;
PStatement typeStatement;
PStatement effetiveTypeStatement = doParseEvalTypeInfo(
fileName, fileName,
varStatement->parentScope.lock(), varStatement->parentScope.lock(),
varStatement->type+ varStatement->args, varStatement->type+varStatement->args,
baseType, baseType,
pointerLevel); typeStatement,
pointerLevel,
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,
pointerLevel effetiveTypeStatement,
pointerLevel,
templateParams
); );
} }
@ -4605,18 +4642,24 @@ PEvalStatement CppParser::doCreateEvalFunction(const QString &fileName, PStateme
return PEvalStatement(); return PEvalStatement();
QString baseType; QString baseType;
int pointerLevel=0; int pointerLevel=0;
PStatement typeStatement = doParseEvalTypeInfo( QString templateParams;
PStatement typeStatement;
PStatement effetiveTypeStatement = doParseEvalTypeInfo(
fileName, fileName,
funcStatement->parentScope.lock(), funcStatement->parentScope.lock(),
funcStatement->type, funcStatement->type,
baseType, baseType,
pointerLevel); typeStatement,
pointerLevel,
templateParams);
return std::make_shared<EvalStatement>( return std::make_shared<EvalStatement>(
baseType, baseType,
EvalStatementKind::Function, EvalStatementKind::Function,
funcStatement, funcStatement,
typeStatement, typeStatement,
pointerLevel effetiveTypeStatement,
pointerLevel,
templateParams
); );
} }
@ -4626,6 +4669,7 @@ PEvalStatement CppParser::doCreateEvalLiteral(const QString &type)
type, type,
EvalStatementKind::Literal, EvalStatementKind::Literal,
PStatement(), PStatement(),
PStatement(),
PStatement()); PStatement());
} }
@ -4652,7 +4696,9 @@ PStatement CppParser::doParseEvalTypeInfo(
const PStatement &scope, const PStatement &scope,
const QString &type, const QString &type,
QString &baseType, QString &baseType,
int &pointerLevel) PStatement& typeStatement,
int &pointerLevel,
QString& templateParams)
{ {
// Remove pointer stuff from type // Remove pointer stuff from type
QString s = type; QString s = type;
@ -4678,6 +4724,7 @@ PStatement CppParser::doParseEvalTypeInfo(
} else if (token == "<") { } else if (token == "<") {
templateLevel++; templateLevel++;
baseType += token; baseType += token;
templateParams += token;
} else if (token == "::") { } else if (token == "::") {
baseType += token; baseType += token;
} }
@ -4694,6 +4741,7 @@ PStatement CppParser::doParseEvalTypeInfo(
templateLevel--; templateLevel--;
} }
baseType += token; baseType += token;
templateParams += token;
} }
highlighter.next(); highlighter.next();
} }
@ -4705,9 +4753,8 @@ PStatement CppParser::doParseEvalTypeInfo(
} }
position--; position--;
} }
PStatement statement = findStatementOf(fileName,baseType,scope,true); typeStatement = findStatementOf(fileName,baseType,scope,true);
return getTypeDef(statement,fileName,baseType); return getTypeDef(typeStatement,fileName,baseType);
} }
int CppParser::getBracketEnd(const QString &s, int startAt) int CppParser::getBracketEnd(const QString &s, int startAt)

View File

@ -391,7 +391,9 @@ private:
const PStatement& scope, const PStatement& scope,
const QString& type, const QString& type,
QString& baseType, QString& baseType,
int& pointerLevel); PStatement& typeStatement,
int& pointerLevel,
QString& templateParams);
int getBracketEnd(const QString& s, int startAt); int getBracketEnd(const QString& s, int startAt);
StatementClassScope getClassScope(const QString& text); StatementClassScope getClassScope(const QString& text);

View File

@ -32,6 +32,7 @@ QSet<QString> CKeywords;
QSet<QString> STLPointers; QSet<QString> STLPointers;
QSet<QString> STLContainers; QSet<QString> STLContainers;
QSet<QString> STLElementMethods; QSet<QString> STLElementMethods;
QSet<QString> STLIterators;
QSet<QString> MemberOperators; QSet<QString> MemberOperators;
QSet<QString> IOManipulators; QSet<QString> IOManipulators;
@ -275,14 +276,20 @@ void initParser()
STLElementMethods.insert("front"); STLElementMethods.insert("front");
STLElementMethods.insert("top"); STLElementMethods.insert("top");
//STL iterator
STLIterators.insert("iterator");
STLIterators.insert("const_iterator");
STLIterators.insert("reverse_iterator");
STLIterators.insert("const_reverse_iterator");
//STL pointers //STL pointers
STLPointers.insert("std::unique_ptr"); STLPointers.insert("std::unique_ptr");
STLPointers.insert("std::auto_ptr"); STLPointers.insert("std::auto_ptr");
STLPointers.insert("std::shared_ptr"); STLPointers.insert("std::shared_ptr");
STLPointers.insert("std::weak_ptr"); STLPointers.insert("std::weak_ptr");
STLPointers.insert("__gnu_cxx::__normal_iterator"); //STLPointers.insert("__gnu_cxx::__normal_iterator");
STLPointers.insert("std::reverse_iterator"); //STLPointers.insert("std::reverse_iterator");
STLPointers.insert("std::iterator"); //STLPointers.insert("std::iterator");
//C/CPP preprocessor directives //C/CPP preprocessor directives
CppDirectives.append("#include"); CppDirectives.append("#include");
@ -568,14 +575,18 @@ EvalStatement::EvalStatement(
const QString &baseType, const QString &baseType,
EvalStatementKind kind, EvalStatementKind kind,
const PStatement &baseStatement, const PStatement &baseStatement,
const PStatement &typeStatement, const PStatement& typeStatement,
int pointerLevel) const PStatement& effectiveTypeStatement,
int pointerLevel,
const QString& templateParams)
{ {
this->baseType = baseType; this->baseType = baseType;
this->kind = kind; this->kind = kind;
this->baseStatement = baseStatement; this->baseStatement = baseStatement;
this->effectiveTypeStatement = typeStatement; this->typeStatement = typeStatement;
this->effectiveTypeStatement = effectiveTypeStatement;
this->pointerLevel = pointerLevel; this->pointerLevel = pointerLevel;
this->templateParams = templateParams;
} }
void EvalStatement::assignType(const PEvalStatement &typeStatement) void EvalStatement::assignType(const PEvalStatement &typeStatement)

View File

@ -239,16 +239,20 @@ using PEvalStatement = std::shared_ptr<EvalStatement>;
*/ */
struct EvalStatement { struct EvalStatement {
QString baseType; // type "int" QString baseType; // type "int"
QString templateParams;
EvalStatementKind kind; // namespace / type / variable / function / literal EvalStatementKind kind; // namespace / type / variable / function / literal
int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"... int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"...
PStatement baseStatement; // if not literal or primitive type, the base statement PStatement baseStatement; // if not literal or primitive type, the base statement
PStatement typeStatement;
PStatement effectiveTypeStatement; PStatement effectiveTypeStatement;
public: public:
EvalStatement (const QString& baseType, EvalStatement (const QString& baseType,
EvalStatementKind kind, EvalStatementKind kind,
const PStatement& baseStatement, const PStatement& baseStatement,
const PStatement& typeStatement, const PStatement& typeStatement,
int pointerLevel = 0); const PStatement& effectiveTypeStatement,
int pointerLevel=0,
const QString& templateParams=QString());
void assignType(const PEvalStatement& typeStatement); void assignType(const PEvalStatement& typeStatement);
}; };
@ -300,6 +304,7 @@ extern QSet<QString> CppTypeKeywords;
extern QSet<QString> STLPointers; extern QSet<QString> STLPointers;
extern QSet<QString> STLContainers; extern QSet<QString> STLContainers;
extern QSet<QString> STLElementMethods; extern QSet<QString> STLElementMethods;
extern QSet<QString> STLIterators;
extern QSet<QString> MemberOperators; extern QSet<QString> MemberOperators;
extern QSet<QString> IOManipulators; extern QSet<QString> IOManipulators;