- enhancement: Parse files that contains C++ 20 'concept' keyword. (No code suggesion for concepts now)
- enhancement: Parse files that contains C++ 20 'requires' keyword. - fix: Code suggestions in namespace. - enhancement: Code suggestions for namespace alias. - fix: Correctly handle statements like 'using xxx::operator()'.
This commit is contained in:
parent
9467645bef
commit
30cabe2faa
5
NEWS.md
5
NEWS.md
|
@ -4,6 +4,11 @@ Red Panda C++ Version 2.26
|
||||||
- enhancement: Auto adjust position of the suggestion popup window.
|
- enhancement: Auto adjust position of the suggestion popup window.
|
||||||
- enhancement: Windows XP support ( by cyano.CN )
|
- enhancement: Windows XP support ( by cyano.CN )
|
||||||
- fix: __attribute__ is not correctly handled if it is after 'static'.
|
- fix: __attribute__ is not correctly handled if it is after 'static'.
|
||||||
|
- enhancement: Parse files that contains C++ 20 'concept' keyword. (No code suggesion for concepts now)
|
||||||
|
- enhancement: Parse files that contains C++ 20 'requires' keyword.
|
||||||
|
- fix: Code suggestions in namespace.
|
||||||
|
- enhancement: Code suggestions for namespace alias.
|
||||||
|
- fix: Correctly handle statements like 'using xxx::operator()'.
|
||||||
|
|
||||||
Red Panda C++ Version 2.25
|
Red Panda C++ Version 2.25
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ QByteArray Compiler::pipedText()
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compiler::beforeRunExtraCommand(int idx)
|
bool Compiler::beforeRunExtraCommand(int /* idx */)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1958,6 +1958,8 @@ bool CppParser::checkForKeyword(KeywordType& keywordType)
|
||||||
case KeywordType::NotKeyword:
|
case KeywordType::NotKeyword:
|
||||||
case KeywordType::DeclType:
|
case KeywordType::DeclType:
|
||||||
case KeywordType::Operator:
|
case KeywordType::Operator:
|
||||||
|
case KeywordType::Requires:
|
||||||
|
case KeywordType::Concept:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
|
@ -2577,6 +2579,19 @@ void CppParser::handleCatchBlock()
|
||||||
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppParser::handleConcept()
|
||||||
|
{
|
||||||
|
mIndex++; // skip 'concept';
|
||||||
|
// just skip it;
|
||||||
|
mIndex = indexOfNextSemicolonOrLeftBrace(mIndex);
|
||||||
|
if (mIndex<mTokenizer.tokenCount()) {
|
||||||
|
if (mTokenizer[mIndex]->text=='{')
|
||||||
|
mIndex = mTokenizer[mIndex]->matchIndex+1; // skip '}'
|
||||||
|
else
|
||||||
|
mIndex++; // skip ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CppParser::handleEnum(bool isTypedef)
|
void CppParser::handleEnum(bool isTypedef)
|
||||||
{
|
{
|
||||||
int tokenCount = mTokenizer.tokenCount();
|
int tokenCount = mTokenizer.tokenCount();
|
||||||
|
@ -3244,6 +3259,17 @@ void CppParser::handleNamespace(KeywordType skipType)
|
||||||
QString aliasName;
|
QString aliasName;
|
||||||
if ((mIndex+2<tokenCount) && (mTokenizer[mIndex]->text == '=')) {
|
if ((mIndex+2<tokenCount) && (mTokenizer[mIndex]->text == '=')) {
|
||||||
aliasName=mTokenizer[mIndex+1]->text;
|
aliasName=mTokenizer[mIndex+1]->text;
|
||||||
|
mIndex+=2;
|
||||||
|
if (aliasName == "::" && mIndex<tokenCount) {
|
||||||
|
aliasName += mTokenizer[mIndex]->text;
|
||||||
|
mIndex++;
|
||||||
|
}
|
||||||
|
while(mIndex+1<tokenCount && mTokenizer[mIndex]->text == "::") {
|
||||||
|
aliasName+="::";
|
||||||
|
aliasName+=mTokenizer[mIndex+1]->text;
|
||||||
|
mIndex+=2;
|
||||||
|
}
|
||||||
|
//qDebug()<<command<<aliasName;
|
||||||
//namespace alias
|
//namespace alias
|
||||||
addStatement(
|
addStatement(
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
|
@ -3259,7 +3285,7 @@ void CppParser::handleNamespace(KeywordType skipType)
|
||||||
getScope(),
|
getScope(),
|
||||||
mCurrentMemberAccessibility,
|
mCurrentMemberAccessibility,
|
||||||
StatementProperty::spHasDefinition);
|
StatementProperty::spHasDefinition);
|
||||||
mIndex+=2; //skip ;
|
mIndex++; // skip ;
|
||||||
return;
|
return;
|
||||||
} else if (isInline) {
|
} else if (isInline) {
|
||||||
//inline namespace , just skip it
|
//inline namespace , just skip it
|
||||||
|
@ -3589,6 +3615,10 @@ bool CppParser::handleStatement()
|
||||||
mIndex=moveToEndOfStatement(mIndex,true);
|
mIndex=moveToEndOfStatement(mIndex,true);
|
||||||
} else if (checkForKeyword(keywordType)) { // includes template now
|
} else if (checkForKeyword(keywordType)) { // includes template now
|
||||||
handleKeyword(keywordType);
|
handleKeyword(keywordType);
|
||||||
|
} else if (keywordType==KeywordType::Concept) {
|
||||||
|
handleConcept();
|
||||||
|
} else if (keywordType==KeywordType::Requires) {
|
||||||
|
skipRequires();
|
||||||
} else if (keywordType==KeywordType::For) { // (for/catch)
|
} else if (keywordType==KeywordType::For) { // (for/catch)
|
||||||
handleForBlock();
|
handleForBlock();
|
||||||
} else if (keywordType==KeywordType::Catch) { // (for/catch)
|
} else if (keywordType==KeywordType::Catch) { // (for/catch)
|
||||||
|
@ -3980,10 +4010,18 @@ void CppParser::handleUsing()
|
||||||
|| (mTokenizer[mIndex]->text != "namespace")) {
|
|| (mTokenizer[mIndex]->text != "namespace")) {
|
||||||
QString fullName;
|
QString fullName;
|
||||||
QString usingName;
|
QString usingName;
|
||||||
|
bool appendUsingName = false;
|
||||||
while (mIndex<tokenCount &&
|
while (mIndex<tokenCount &&
|
||||||
mTokenizer[mIndex]->text!=';') {
|
mTokenizer[mIndex]->text!=';') {
|
||||||
fullName += mTokenizer[mIndex]->text;
|
fullName += mTokenizer[mIndex]->text;
|
||||||
usingName = mTokenizer[mIndex]->text;
|
if (!appendUsingName) {
|
||||||
|
usingName = mTokenizer[mIndex]->text;
|
||||||
|
if (usingName == "operator") {
|
||||||
|
appendUsingName=true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usingName += mTokenizer[mIndex]->text;
|
||||||
|
}
|
||||||
mIndex++;
|
mIndex++;
|
||||||
}
|
}
|
||||||
if (fullName!=usingName) {
|
if (fullName!=usingName) {
|
||||||
|
@ -4327,6 +4365,43 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
|
||||||
mIndex++;
|
mIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppParser::skipRequires()
|
||||||
|
{
|
||||||
|
mIndex++; //skip 'requires';
|
||||||
|
|
||||||
|
int tokenCount = mTokenizer.tokenCount();
|
||||||
|
while (mIndex < tokenCount) { // ||
|
||||||
|
while (mIndex < tokenCount) { // &&
|
||||||
|
if (mTokenizer[mIndex]->text=='(') {
|
||||||
|
//skip parenthesized expression
|
||||||
|
mIndex = mTokenizer[mIndex]->matchIndex+1;
|
||||||
|
} else if (isIdentifier(mTokenizer[mIndex]->text)) {
|
||||||
|
// skip foo<T> or foo::boo::ttt<T>
|
||||||
|
while (mIndex < tokenCount) {
|
||||||
|
if (!isIdentifier(mTokenizer[mIndex]->text))
|
||||||
|
return;
|
||||||
|
mIndex++;
|
||||||
|
if (mIndex>=tokenCount)
|
||||||
|
return;
|
||||||
|
if (mTokenizer[mIndex]->text!="::")
|
||||||
|
break;
|
||||||
|
mIndex++; // skip '::';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mIndex>=tokenCount)
|
||||||
|
return;
|
||||||
|
if (mTokenizer[mIndex]->text!="&&")
|
||||||
|
break;
|
||||||
|
mIndex++; // skip '&&';
|
||||||
|
}
|
||||||
|
if (mIndex>=tokenCount)
|
||||||
|
return;
|
||||||
|
if (mTokenizer[mIndex]->text!="||")
|
||||||
|
break;
|
||||||
|
mIndex++; // skip '||';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CppParser::internalParse(const QString &fileName)
|
void CppParser::internalParse(const QString &fileName)
|
||||||
{
|
{
|
||||||
// Perform some validation before we start
|
// Perform some validation before we start
|
||||||
|
@ -5209,6 +5284,9 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
case StatementKind::skNamespace:
|
case StatementKind::skNamespace:
|
||||||
result = doCreateEvalNamespace(statement);
|
result = doCreateEvalNamespace(statement);
|
||||||
break;
|
break;
|
||||||
|
case StatementKind::skNamespaceAlias:
|
||||||
|
result = doFindAliasedNamespace(statement);
|
||||||
|
break;
|
||||||
case StatementKind::skAlias: {
|
case StatementKind::skAlias: {
|
||||||
statement = doFindAliasedStatement(statement);
|
statement = doFindAliasedStatement(statement);
|
||||||
if (statement)
|
if (statement)
|
||||||
|
@ -5421,6 +5499,29 @@ PEvalStatement CppParser::doCreateEvalNamespace(const PStatement &namespaceState
|
||||||
namespaceStatement);
|
namespaceStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEvalStatement CppParser::doFindAliasedNamespace(const PStatement &namespaceAlias) const
|
||||||
|
{
|
||||||
|
QStringList expList;
|
||||||
|
QString s = namespaceAlias->type;
|
||||||
|
int pos = s.indexOf("::");
|
||||||
|
while (pos>=0) {
|
||||||
|
expList.append(s.left(pos));
|
||||||
|
expList.append("::");
|
||||||
|
s = s.mid(pos+2);
|
||||||
|
pos = s.indexOf("::");
|
||||||
|
}
|
||||||
|
expList.append(s);
|
||||||
|
pos=0;
|
||||||
|
return doEvalExpression(
|
||||||
|
namespaceAlias->fileName,
|
||||||
|
expList,
|
||||||
|
pos,
|
||||||
|
namespaceAlias->parentScope.lock(),
|
||||||
|
PEvalStatement(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
PEvalStatement CppParser::doCreateEvalType(const QString &fileName, const QString &typeName, const PStatement& parentScope) const
|
PEvalStatement CppParser::doCreateEvalType(const QString &fileName, const QString &typeName, const PStatement& parentScope) const
|
||||||
{
|
{
|
||||||
QString baseType;
|
QString baseType;
|
||||||
|
|
|
@ -223,11 +223,13 @@ private:
|
||||||
int evaluateConstExprTerm(int endIndex, bool &ok);
|
int evaluateConstExprTerm(int endIndex, bool &ok);
|
||||||
int evaluateLiteralNumber(int endIndex, bool &ok);
|
int evaluateLiteralNumber(int endIndex, bool &ok);
|
||||||
|
|
||||||
|
bool checkForConcept(KeywordType &keywordType) { return keywordType == KeywordType::Concept; }
|
||||||
bool checkForKeyword(KeywordType &keywordType);
|
bool checkForKeyword(KeywordType &keywordType);
|
||||||
bool checkForNamespace(KeywordType keywordType);
|
bool checkForNamespace(KeywordType keywordType);
|
||||||
bool checkForPreprocessor();
|
bool checkForPreprocessor();
|
||||||
// bool checkForLambda();
|
// bool checkForLambda();
|
||||||
bool checkForAccessibilitySpecifiers(KeywordType keywordType);
|
bool checkForAccessibilitySpecifiers(KeywordType keywordType);
|
||||||
|
bool checkForRequires(KeywordType keywordType) { return keywordType == KeywordType::Requires; }
|
||||||
bool checkForStructs(KeywordType keywordType);
|
bool checkForStructs(KeywordType keywordType);
|
||||||
bool checkForTypedefEnum();
|
bool checkForTypedefEnum();
|
||||||
bool checkForTypedefStruct();
|
bool checkForTypedefStruct();
|
||||||
|
@ -371,6 +373,8 @@ private:
|
||||||
|
|
||||||
PEvalStatement doCreateEvalNamespace(const PStatement& namespaceStatement) const;
|
PEvalStatement doCreateEvalNamespace(const PStatement& namespaceStatement) const;
|
||||||
|
|
||||||
|
PEvalStatement doFindAliasedNamespace(const PStatement& namespaceAlias) const;
|
||||||
|
|
||||||
PEvalStatement doCreateEvalType(const QString& fileName,const QString& typeName, const PStatement& parentScope) const;
|
PEvalStatement doCreateEvalType(const QString& fileName,const QString& typeName, const PStatement& parentScope) const;
|
||||||
PEvalStatement doCreateEvalType(const QString& fileName,const PStatement& typeStatement) const;
|
PEvalStatement doCreateEvalType(const QString& fileName,const PStatement& typeStatement) const;
|
||||||
PEvalStatement doCreateEvalType(const QString& primitiveType) const;
|
PEvalStatement doCreateEvalType(const QString& primitiveType) const;
|
||||||
|
@ -485,6 +489,7 @@ private:
|
||||||
PStatement getTypeDef(const PStatement& statement,
|
PStatement getTypeDef(const PStatement& statement,
|
||||||
const QString& fileName, const QString& aType) const;
|
const QString& fileName, const QString& aType) const;
|
||||||
void handleCatchBlock();
|
void handleCatchBlock();
|
||||||
|
void handleConcept();
|
||||||
void handleEnum(bool isTypedef);
|
void handleEnum(bool isTypedef);
|
||||||
void handleForBlock();
|
void handleForBlock();
|
||||||
void handleKeyword(KeywordType skipType);
|
void handleKeyword(KeywordType skipType);
|
||||||
|
@ -510,6 +515,7 @@ private:
|
||||||
void handleStructs(bool isTypedef = false);
|
void handleStructs(bool isTypedef = false);
|
||||||
void handleUsing();
|
void handleUsing();
|
||||||
void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
|
void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
|
||||||
|
void skipRequires();
|
||||||
void internalParse(const QString& fileName);
|
void internalParse(const QString& fileName);
|
||||||
// function FindMacroDefine(const Command: AnsiString): PStatement;
|
// function FindMacroDefine(const Command: AnsiString): PStatement;
|
||||||
void inheritClassStatement(
|
void inheritClassStatement(
|
||||||
|
|
|
@ -135,20 +135,21 @@ void initParser()
|
||||||
CppKeywords.insert("__asm",KeywordType::SkipNextParenthesis);
|
CppKeywords.insert("__asm",KeywordType::SkipNextParenthesis);
|
||||||
// Skip to {
|
// Skip to {
|
||||||
|
|
||||||
|
CppKeywords.insert("requires",KeywordType::Requires);
|
||||||
|
CppKeywords.insert("concept",KeywordType::Concept);
|
||||||
|
|
||||||
// wont handle
|
// wont handle
|
||||||
|
|
||||||
//Not supported yet
|
//Not supported yet
|
||||||
CppKeywords.insert("atomic_cancel",KeywordType::None);
|
CppKeywords.insert("atomic_cancel",KeywordType::None);
|
||||||
CppKeywords.insert("atomic_commit",KeywordType::None);
|
CppKeywords.insert("atomic_commit",KeywordType::None);
|
||||||
CppKeywords.insert("atomic_noexcept",KeywordType::None);
|
CppKeywords.insert("atomic_noexcept",KeywordType::None);
|
||||||
CppKeywords.insert("concept",KeywordType::None);
|
|
||||||
CppKeywords.insert("consteval",KeywordType::None);
|
CppKeywords.insert("consteval",KeywordType::None);
|
||||||
CppKeywords.insert("constinit",KeywordType::None);
|
CppKeywords.insert("constinit",KeywordType::None);
|
||||||
CppKeywords.insert("co_wait",KeywordType::None);
|
CppKeywords.insert("co_wait",KeywordType::None);
|
||||||
CppKeywords.insert("co_return",KeywordType::None);
|
CppKeywords.insert("co_return",KeywordType::None);
|
||||||
CppKeywords.insert("co_yield",KeywordType::None);
|
CppKeywords.insert("co_yield",KeywordType::None);
|
||||||
CppKeywords.insert("reflexpr",KeywordType::None);
|
CppKeywords.insert("reflexpr",KeywordType::None);
|
||||||
CppKeywords.insert("requires",KeywordType::None);
|
|
||||||
|
|
||||||
// its a type
|
// its a type
|
||||||
CppKeywords.insert("auto",KeywordType::None);
|
CppKeywords.insert("auto",KeywordType::None);
|
||||||
|
|
|
@ -81,6 +81,8 @@ enum class KeywordType {
|
||||||
Using, //using
|
Using, //using
|
||||||
DeclType, // decltype
|
DeclType, // decltype
|
||||||
Operator, //operator
|
Operator, //operator
|
||||||
|
Concept, //concept
|
||||||
|
Requires, //requires
|
||||||
None, // It's a keyword but don't process here
|
None, // It's a keyword but don't process here
|
||||||
NotKeyword
|
NotKeyword
|
||||||
};
|
};
|
||||||
|
|
|
@ -664,7 +664,13 @@ void CodeCompletionPopup::getCompletionFor(
|
||||||
// repeat until reach global
|
// repeat until reach global
|
||||||
while (scopeStatement) {
|
while (scopeStatement) {
|
||||||
//add members of current scope that not added before
|
//add members of current scope that not added before
|
||||||
if (scopeStatement->kind == StatementKind::skClass) {
|
if (scopeStatement->kind == StatementKind::skNamespace) {
|
||||||
|
PStatementList namespaceStatementsList =
|
||||||
|
mParser->findNamespace(scopeStatement->fullName);
|
||||||
|
foreach (const PStatement& namespaceStatement,*namespaceStatementsList) {
|
||||||
|
addChildren(namespaceStatement, fileName, line, isLambdaReturnType);
|
||||||
|
}
|
||||||
|
} else if (scopeStatement->kind == StatementKind::skClass) {
|
||||||
addChildren(scopeStatement, fileName, -1, isLambdaReturnType);
|
addChildren(scopeStatement, fileName, -1, isLambdaReturnType);
|
||||||
} else {
|
} else {
|
||||||
addChildren(scopeStatement, fileName, line, isLambdaReturnType);
|
addChildren(scopeStatement, fileName, line, isLambdaReturnType);
|
||||||
|
|
|
@ -148,7 +148,7 @@ public:
|
||||||
virtual bool getTokenFinished() const = 0;
|
virtual bool getTokenFinished() const = 0;
|
||||||
virtual bool isLastLineCommentNotFinished(int state) const = 0;
|
virtual bool isLastLineCommentNotFinished(int state) const = 0;
|
||||||
virtual bool isLastLineStringNotFinished(int state) const = 0;
|
virtual bool isLastLineStringNotFinished(int state) const = 0;
|
||||||
virtual bool isDocstringNotFinished(int state) const { return false; }
|
virtual bool isDocstringNotFinished(int /* state */) const { return false; }
|
||||||
virtual bool eol() const = 0;
|
virtual bool eol() const = 0;
|
||||||
virtual SyntaxState getState() const = 0;
|
virtual SyntaxState getState() const = 0;
|
||||||
virtual QString getToken() const=0;
|
virtual QString getToken() const=0;
|
||||||
|
|
Loading…
Reference in New Issue