- 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
- enhancement: show completion suggest for "namespace" after "using"
- 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: can't correctly show completion suggest for type with template parameters
Red Panda C++ Version 2.4

View File

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

View File

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

View File

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

View File

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

View File

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