- fix: Dummy struct/enum symbols shouldn't be shown in the completion suggestion.
- enhancement: Support optional enum name. - enhancement: Support optional enum type. - enhancement: Support simple const expression evaluation for enum values. - fix: Accessibilty for inherited members are not correct calculated in multiple inheritance. - fix: Can't handle full class name when handle inheritance.
This commit is contained in:
parent
dd724e64c2
commit
6a06b5b3d6
8
NEWS.md
8
NEWS.md
|
@ -10,6 +10,12 @@ Red Panda C++ Version 2.24
|
||||||
- enhancement: Press left/right arrow will move caret to the begin/end of the selection.
|
- enhancement: Press left/right arrow will move caret to the begin/end of the selection.
|
||||||
- enhancement: Press up/down arrow will move caret up/down from the begin/end of the selection.
|
- enhancement: Press up/down arrow will move caret up/down from the begin/end of the selection.
|
||||||
- enhancement: Show progress dialog if the time for searching compilers is too long.
|
- enhancement: Show progress dialog if the time for searching compilers is too long.
|
||||||
|
- fix: Dummy struct/enum symbols shouldn't be shown in the completion suggestion.
|
||||||
|
- enhancement: Support optional enum name.
|
||||||
|
- enhancement: Support optional enum type.
|
||||||
|
- enhancement: Support simple const expression evaluation for enum values.
|
||||||
|
- fix: Accessibilty for inherited members are not correct calculated in multiple inheritance.
|
||||||
|
- fix: Can't handle full class name when handle inheritance.
|
||||||
|
|
||||||
|
|
||||||
Red Panda C++ Version 2.23
|
Red Panda C++ Version 2.23
|
||||||
|
@ -1054,7 +1060,7 @@ Red Panda C++ Version 0.14.0
|
||||||
- enhancement: show custom icon set folder in options -> enviroment -> folders
|
- enhancement: show custom icon set folder in options -> enviroment -> folders
|
||||||
- enhancement: new class ( to project) wizard
|
- enhancement: new class ( to project) wizard
|
||||||
- enhancement: greatly speed up code completion
|
- enhancement: greatly speed up code completion
|
||||||
- fix: code folding calcuation not correct when some codes are folded and editing after them
|
- fix: code folding calculation not correct when some codes are folded and editing after them
|
||||||
- enhancement: code completion ui redesigned
|
- enhancement: code completion ui redesigned
|
||||||
- fix: mainwindow action's short cut doesn't work, if the action is not in menu or toolbar
|
- fix: mainwindow action's short cut doesn't work, if the action is not in menu or toolbar
|
||||||
- fix: when run all cases for a problem, processing of output is slow
|
- fix: when run all cases for a problem, processing of output is slow
|
||||||
|
|
|
@ -4018,28 +4018,6 @@ QString Editor::getParserHint(const QStringList& expression,const QString &/*s*/
|
||||||
if (statement->kind == StatementKind::skFunction
|
if (statement->kind == StatementKind::skFunction
|
||||||
|| statement->kind == StatementKind::skConstructor
|
|| statement->kind == StatementKind::skConstructor
|
||||||
|| statement->kind == StatementKind::skDestructor) {
|
|| statement->kind == StatementKind::skDestructor) {
|
||||||
//PStatement parentScope = statement->parentScope.lock();
|
|
||||||
// if (parentScope && parentScope->kind == StatementKind::skNamespace) {
|
|
||||||
// PStatementList namespaceStatementsList =
|
|
||||||
// mParser->findNamespace(parentScope->command);
|
|
||||||
// if (namespaceStatementsList) {
|
|
||||||
// int counts=0;
|
|
||||||
// foreach (const PStatement& namespaceStatement, *namespaceStatementsList) {
|
|
||||||
// QString hint = getHintForFunction(statement,namespaceStatement,
|
|
||||||
// mFilename,line);
|
|
||||||
// if (!hint.isEmpty()) {
|
|
||||||
// counts++;
|
|
||||||
// if (!result.isEmpty())
|
|
||||||
// result += "\n";
|
|
||||||
// if (counts>4) {
|
|
||||||
// result += "...";
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// result += hint;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else
|
|
||||||
result = getHintForFunction(statement,mFilename,line);
|
result = getHintForFunction(statement,mFilename,line);
|
||||||
} else if (statement->line>0) {
|
} else if (statement->line>0) {
|
||||||
QFileInfo fileInfo(statement->fileName);
|
QFileInfo fileInfo(statement->fileName);
|
||||||
|
|
|
@ -266,7 +266,9 @@ PStatement CppParser::doFindStatement(const QString &fullname) const
|
||||||
return PStatement();
|
return PStatement();
|
||||||
PStatement parentStatement;
|
PStatement parentStatement;
|
||||||
PStatement statement;
|
PStatement statement;
|
||||||
foreach (const QString& phrase, phrases) {
|
|
||||||
|
for (int i=(phrases[0].isEmpty()?1:0);i<phrases.count();i++) {
|
||||||
|
const QString& phrase=phrases[i];
|
||||||
if (parentStatement && parentStatement->kind == StatementKind::skNamespace) {
|
if (parentStatement && parentStatement->kind == StatementKind::skNamespace) {
|
||||||
PStatementList lst = doFindNamespace(parentStatement->fullName);
|
PStatementList lst = doFindNamespace(parentStatement->fullName);
|
||||||
foreach (const PStatement& namespaceStatement, *lst) {
|
foreach (const PStatement& namespaceStatement, *lst) {
|
||||||
|
@ -1143,7 +1145,13 @@ QString CppParser::prettyPrintStatement(const PStatement& statement, const QStri
|
||||||
result = "enum "+statement->command;
|
result = "enum "+statement->command;
|
||||||
break;
|
break;
|
||||||
case StatementKind::skEnum:
|
case StatementKind::skEnum:
|
||||||
result = statement->type + "::" + statement->command;
|
if (!statement->type.isEmpty())
|
||||||
|
result = statement->type + "::";
|
||||||
|
else
|
||||||
|
result = "";
|
||||||
|
result += statement->command;
|
||||||
|
if (!statement->value.isEmpty())
|
||||||
|
result += "(" + statement->value + ")";
|
||||||
break;
|
break;
|
||||||
case StatementKind::skTypedef:
|
case StatementKind::skTypedef:
|
||||||
result = "typedef "+statement->type+" "+statement->command;
|
result = "typedef "+statement->type+" "+statement->command;
|
||||||
|
@ -1518,25 +1526,53 @@ 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 == StatementAccessibility::None) {
|
} else if (inheritScopeType == StatementAccessibility::None) {
|
||||||
if (currentText !=','
|
if (currentText=="::"
|
||||||
&& currentText!=':') {
|
|| isIdentChar(currentText[0])) {
|
||||||
|
|
||||||
|
|
||||||
QString basename = currentText;
|
QString basename = currentText;
|
||||||
|
bool isGlobal = false;
|
||||||
|
index++;
|
||||||
|
if (basename=="::") {
|
||||||
|
if (index>=tokenCount || !isIdentChar(mTokenizer[index]->text[0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isGlobal=true;
|
||||||
|
basename=mTokenizer[index]->text;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
//remove template staff
|
//remove template staff
|
||||||
if (basename.endsWith('>')) {
|
if (basename.endsWith('>')) {
|
||||||
int pBegin = basename.indexOf('<');
|
int pBegin = basename.indexOf('<');
|
||||||
if (pBegin>=0)
|
if (pBegin>=0)
|
||||||
basename.truncate(pBegin);
|
basename.truncate(pBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (index+1<tokenCount
|
||||||
|
&& mTokenizer[index]->text=="::"
|
||||||
|
&& isIdentChar(mTokenizer[index+1]->text[0])){
|
||||||
|
basename += "::" + mTokenizer[index+1]->text;
|
||||||
|
index+=2;
|
||||||
|
//remove template staff
|
||||||
|
if (basename.endsWith('>')) {
|
||||||
|
int pBegin = basename.indexOf('<');
|
||||||
|
if (pBegin>=0)
|
||||||
|
basename.truncate(pBegin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find the corresponding PStatement
|
// Find the corresponding PStatement
|
||||||
PStatement statement = doFindStatementOf(mCurrentFile,basename,
|
PStatement statement = doFindStatementOf(mCurrentFile,basename,
|
||||||
classStatement->parentScope.lock());
|
isGlobal?PStatement():classStatement->parentScope.lock());
|
||||||
if (statement && statement->kind == StatementKind::skClass) {
|
if (statement && statement->kind == StatementKind::skClass) {
|
||||||
inheritClassStatement(classStatement,isStruct,statement,lastInheritScopeType);
|
inheritClassStatement(classStatement,isStruct,statement,lastInheritScopeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
lastInheritScopeType = inheritScopeType;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
lastInheritScopeType = inheritScopeType;
|
|
||||||
if (index >= tokenCount)
|
if (index >= tokenCount)
|
||||||
break;
|
break;
|
||||||
if (mTokenizer[index]->text.front() == '{'
|
if (mTokenizer[index]->text.front() == '{'
|
||||||
|
@ -1717,6 +1753,174 @@ QStringList CppParser::sortFilesByIncludeRelations(const QSet<QString> &files)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CppParser::evaluateConstExpr(int endIndex, bool &ok)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (mIndex>=endIndex) {
|
||||||
|
ok=false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
result = evaluateAdditionConstExpr(endIndex,ok);
|
||||||
|
if (mIndex!=endIndex)
|
||||||
|
ok = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CppParser::evaluateAdditionConstExpr(int endIndex, bool &ok)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (mIndex>=endIndex) {
|
||||||
|
ok=false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
result = evaluateMultiplyConstExpr(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
while (mIndex<endIndex) {
|
||||||
|
if (mTokenizer[mIndex]->text=='+') {
|
||||||
|
mIndex++;
|
||||||
|
int temp = evaluateMultiplyConstExpr(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
result+=temp;
|
||||||
|
} else if (mTokenizer[mIndex]->text=='-') {
|
||||||
|
mIndex++;
|
||||||
|
int temp = evaluateMultiplyConstExpr(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
result-=temp;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CppParser::evaluateMultiplyConstExpr(int endIndex, bool &ok)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (mIndex>=endIndex) {
|
||||||
|
ok=false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
result = evaluateConstExprTerm(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
while (mIndex<endIndex) {
|
||||||
|
if (mTokenizer[mIndex]->text=='*') {
|
||||||
|
mIndex++;
|
||||||
|
int temp = evaluateConstExprTerm(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
result*=temp;
|
||||||
|
} else if (mTokenizer[mIndex]->text=='/') {
|
||||||
|
mIndex++;
|
||||||
|
int temp = evaluateConstExprTerm(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
result/=temp;
|
||||||
|
} else if (mTokenizer[mIndex]->text=='%') {
|
||||||
|
mIndex++;
|
||||||
|
int temp = evaluateConstExprTerm(endIndex,ok);
|
||||||
|
if (!ok)
|
||||||
|
return result;
|
||||||
|
result%=temp;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CppParser::evaluateConstExprTerm(int endIndex, bool &ok)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (mIndex>=endIndex) {
|
||||||
|
ok=false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mTokenizer[mIndex]->text=="(") {
|
||||||
|
mIndex++;
|
||||||
|
result = evaluateConstExpr(endIndex, ok);
|
||||||
|
if (mIndex>=endIndex || mTokenizer[mIndex]->text!=')')
|
||||||
|
ok=false;
|
||||||
|
mIndex++;
|
||||||
|
} else if (isIdentChar(mTokenizer[mIndex]->text[0])
|
||||||
|
|| mTokenizer[mIndex]->text=="::") {
|
||||||
|
QString s = mTokenizer[mIndex]->text;
|
||||||
|
QSet<QString> searched;
|
||||||
|
mIndex++;
|
||||||
|
if (s=="::") {
|
||||||
|
if (mIndex>=endIndex || !isIdentChar(mTokenizer[mIndex]->text[0])) {
|
||||||
|
ok=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
s+=mTokenizer[mIndex]->text;
|
||||||
|
mIndex++;
|
||||||
|
}
|
||||||
|
while (mIndex+1<endIndex
|
||||||
|
&& mTokenizer[mIndex]->text=="::"
|
||||||
|
&& isIdentChar(mTokenizer[mIndex+1]->text[0])){
|
||||||
|
s += "::" + mTokenizer[mIndex+1]->text;
|
||||||
|
mIndex+=2;
|
||||||
|
}
|
||||||
|
while (true){
|
||||||
|
//prevent infinite loop
|
||||||
|
if (searched.contains(s)) {
|
||||||
|
ok=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
searched.insert(s);
|
||||||
|
PStatement statement = doFindStatement(s);
|
||||||
|
if (!statement) {
|
||||||
|
ok=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (statement->kind == StatementKind::skEnum) {
|
||||||
|
result = statement->value.toInt(&ok);
|
||||||
|
break;
|
||||||
|
} else if (statement->kind == StatementKind::skPreprocessor) {
|
||||||
|
if (!statement->args.isEmpty()) {
|
||||||
|
ok=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
QString macroText = statement->value;
|
||||||
|
if (macroText.isEmpty()) {
|
||||||
|
ok=false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (isDigitChar(macroText[0])) {
|
||||||
|
result = evaluateLiteralNumber(endIndex,ok);
|
||||||
|
} else {
|
||||||
|
s = macroText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = evaluateLiteralNumber(endIndex,ok);
|
||||||
|
mIndex++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CppParser::evaluateLiteralNumber(int endIndex, bool &ok)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (mIndex>=endIndex) {
|
||||||
|
ok=false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mTokenizer[mIndex]->text.startsWith("0x")
|
||||||
|
|| mTokenizer[mIndex]->text.startsWith("0X"))
|
||||||
|
result = mTokenizer[mIndex]->text.mid(2).toInt(&ok,16);
|
||||||
|
else if (mTokenizer[mIndex]->text.startsWith("0b")
|
||||||
|
|| mTokenizer[mIndex]->text.startsWith("0B"))
|
||||||
|
result = mTokenizer[mIndex]->text.mid(2).toInt(&ok,2);
|
||||||
|
else if (mTokenizer[mIndex]->text.startsWith("0"))
|
||||||
|
result = mTokenizer[mIndex]->text.toInt(&ok,8);
|
||||||
|
else
|
||||||
|
result = mTokenizer[mIndex]->text.toInt(&ok);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool CppParser::checkForKeyword(KeywordType& keywordType)
|
bool CppParser::checkForKeyword(KeywordType& keywordType)
|
||||||
{
|
{
|
||||||
keywordType = mCppKeywords.value(mTokenizer[mIndex]->text,KeywordType::NotKeyword);
|
keywordType = mCppKeywords.value(mTokenizer[mIndex]->text,KeywordType::NotKeyword);
|
||||||
|
@ -2349,9 +2553,9 @@ void CppParser::handleEnum(bool isTypedef)
|
||||||
//enum class
|
//enum class
|
||||||
isEnumClass = true;
|
isEnumClass = true;
|
||||||
mIndex++; //skip class
|
mIndex++; //skip class
|
||||||
|
|
||||||
}
|
}
|
||||||
bool isAdhocVar=false;
|
bool isAdhocVar=false;
|
||||||
|
bool isNonameEnum=false;
|
||||||
int endIndex=-1;
|
int endIndex=-1;
|
||||||
if ((mIndex< tokenCount) && mTokenizer[mIndex]->text.startsWith('{')) { // enum {...} NAME
|
if ((mIndex< tokenCount) && mTokenizer[mIndex]->text.startsWith('{')) { // enum {...} NAME
|
||||||
// Skip to the closing brace
|
// Skip to the closing brace
|
||||||
|
@ -2360,9 +2564,12 @@ void CppParser::handleEnum(bool isTypedef)
|
||||||
if (i + 1 < tokenCount) {
|
if (i + 1 < tokenCount) {
|
||||||
enumName = mTokenizer[i + 1]->text.trimmed();
|
enumName = mTokenizer[i + 1]->text.trimmed();
|
||||||
if (!isIdentifierOrPointer(enumName)) {
|
if (!isIdentifierOrPointer(enumName)) {
|
||||||
//not a valid enum, skip to j
|
if (isTypedef || isEnumClass) {
|
||||||
mIndex=indexOfNextSemicolon(i+1)+1;
|
//not a valid enum, skip to j
|
||||||
return;
|
mIndex=indexOfNextSemicolon(i+1)+1;
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
isNonameEnum = true;
|
||||||
}
|
}
|
||||||
if (!isTypedef) {
|
if (!isTypedef) {
|
||||||
//it's an ad-hoc enum var define;
|
//it's an ad-hoc enum var define;
|
||||||
|
@ -2371,13 +2578,20 @@ void CppParser::handleEnum(bool isTypedef)
|
||||||
mIndex=indexOfNextSemicolon(i+1)+1;
|
mIndex=indexOfNextSemicolon(i+1)+1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enumName = "__enum__"+enumName+"__";
|
enumName = "__@enum@__"+enumName+"__";
|
||||||
isAdhocVar=true;
|
isAdhocVar=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endIndex=i+1;
|
endIndex=i+1;
|
||||||
} else if (mIndex+1< tokenCount && mTokenizer[mIndex+1]->text.startsWith('{')){ // enum NAME {...};
|
} else if (mIndex+1< tokenCount && mTokenizer[mIndex+1]->text.startsWith('{')){ // enum NAME {...};
|
||||||
enumName = mTokenizer[mIndex]->text;
|
enumName = mTokenizer[mIndex]->text;
|
||||||
|
mIndex++;
|
||||||
|
} else if (mIndex+1< tokenCount && mTokenizer[mIndex+1]->text.startsWith(':')){ // enum NAME:int {...};
|
||||||
|
enumName = mTokenizer[mIndex]->text;
|
||||||
|
//skip :
|
||||||
|
mIndex = indexOfNextLeftBrace(mIndex);
|
||||||
|
if (mIndex>tokenCount)
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
// enum NAME blahblah
|
// enum NAME blahblah
|
||||||
// it's an old c-style enum variable definition
|
// it's an old c-style enum variable definition
|
||||||
|
@ -2386,34 +2600,37 @@ void CppParser::handleEnum(bool isTypedef)
|
||||||
|
|
||||||
// Add statement for enum name too
|
// Add statement for enum name too
|
||||||
PStatement enumStatement;
|
PStatement enumStatement;
|
||||||
if (isEnumClass) {
|
if (!isNonameEnum) {
|
||||||
enumStatement=addStatement(
|
if (isEnumClass) {
|
||||||
getCurrentScope(),
|
enumStatement=addStatement(
|
||||||
mCurrentFile,
|
getCurrentScope(),
|
||||||
"enum class",
|
mCurrentFile,
|
||||||
enumName,
|
"enum class",
|
||||||
"",
|
enumName,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
startLine,
|
"",
|
||||||
StatementKind::skEnumClassType,
|
startLine,
|
||||||
getScope(),
|
StatementKind::skEnumClassType,
|
||||||
mCurrentMemberAccessibility,
|
getScope(),
|
||||||
StatementProperty::spHasDefinition);
|
mCurrentMemberAccessibility,
|
||||||
} else {
|
StatementProperty::spHasDefinition);
|
||||||
enumStatement=addStatement(
|
} else {
|
||||||
getCurrentScope(),
|
enumStatement=addStatement(
|
||||||
mCurrentFile,
|
getCurrentScope(),
|
||||||
"enum",
|
mCurrentFile,
|
||||||
enumName,
|
"enum",
|
||||||
"",
|
enumName,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
startLine,
|
"",
|
||||||
StatementKind::skEnumType,
|
startLine,
|
||||||
getScope(),
|
StatementKind::skEnumType,
|
||||||
mCurrentMemberAccessibility,
|
getScope(),
|
||||||
StatementProperty::spHasDefinition);
|
mCurrentMemberAccessibility,
|
||||||
|
isAdhocVar?(StatementProperty::spHasDefinition|StatementProperty::spDummyStatement)
|
||||||
|
:StatementProperty::spHasDefinition );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isAdhocVar) {
|
if (isAdhocVar) {
|
||||||
//Ad-hoc var definition
|
//Ad-hoc var definition
|
||||||
|
@ -2454,69 +2671,81 @@ void CppParser::handleEnum(bool isTypedef)
|
||||||
mIndex++;
|
mIndex++;
|
||||||
|
|
||||||
// Call every member "enum NAME ITEMNAME"
|
// Call every member "enum NAME ITEMNAME"
|
||||||
QString lastType("enum");
|
QString lastType;
|
||||||
if (!enumName.isEmpty())
|
if (enumStatement && !isAdhocVar)
|
||||||
lastType += ' ' + enumName;
|
lastType = "enum " + enumName;
|
||||||
QString cmd;
|
QString cmd;
|
||||||
QString args;
|
QString args;
|
||||||
if (mTokenizer[mIndex]->text!='}') {
|
int value=0;
|
||||||
while ((mIndex < tokenCount) &&
|
bool canCalcValue=true;
|
||||||
mTokenizer[mIndex]->text!='}') {
|
while ((mIndex < tokenCount) &&
|
||||||
if (mTokenizer[mIndex]->text=="=") {
|
mTokenizer[mIndex]->text!='}') {
|
||||||
mIndex=indexOfNextPeriodOrSemicolon(mIndex);
|
if (tokenIsIdentifier(mTokenizer[mIndex]->text)) {
|
||||||
continue;
|
cmd = mTokenizer[mIndex]->text;
|
||||||
} else if (tokenIsIdentifier(mTokenizer[mIndex]->text)) {
|
args = "";
|
||||||
cmd = mTokenizer[mIndex]->text;
|
if (mIndex+1<tokenCount &&
|
||||||
args = "";
|
mTokenizer[mIndex+1]->text=="=") {
|
||||||
if (isEnumClass) {
|
mIndex+=2;
|
||||||
if (enumStatement) {
|
if (mIndex<tokenCount) {
|
||||||
addStatement(
|
bool ok;
|
||||||
enumStatement,
|
int endIndex = indexOfNextPeriodOrSemicolon(mIndex);
|
||||||
mCurrentFile,
|
value = evaluateConstExpr(endIndex,ok);
|
||||||
lastType,
|
if (!ok) {
|
||||||
cmd,
|
canCalcValue=false;
|
||||||
args,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
mTokenizer[mIndex]->line,
|
|
||||||
StatementKind::skEnum,
|
|
||||||
getScope(),
|
|
||||||
mCurrentMemberAccessibility,
|
|
||||||
StatementProperty::spHasDefinition);
|
|
||||||
}
|
}
|
||||||
} else {
|
mIndex = endIndex - 1;
|
||||||
if (enumStatement) {
|
|
||||||
addStatement(
|
|
||||||
enumStatement,
|
|
||||||
mCurrentFile,
|
|
||||||
lastType,
|
|
||||||
cmd,
|
|
||||||
args,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
mTokenizer[mIndex]->line,
|
|
||||||
StatementKind::skEnum,
|
|
||||||
getScope(),
|
|
||||||
mCurrentMemberAccessibility,
|
|
||||||
StatementProperty::spHasDefinition);
|
|
||||||
}
|
|
||||||
addStatement(
|
|
||||||
getCurrentScope(),
|
|
||||||
mCurrentFile,
|
|
||||||
lastType,
|
|
||||||
cmd,
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
mTokenizer[mIndex]->line,
|
|
||||||
StatementKind::skEnum,
|
|
||||||
getScope(),
|
|
||||||
mCurrentMemberAccessibility,
|
|
||||||
StatementProperty::spHasDefinition);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mIndex ++ ;
|
if (isEnumClass) {
|
||||||
|
if (enumStatement) {
|
||||||
|
addStatement(
|
||||||
|
enumStatement,
|
||||||
|
mCurrentFile,
|
||||||
|
lastType,
|
||||||
|
cmd,
|
||||||
|
args,
|
||||||
|
"",
|
||||||
|
canCalcValue?QString("%1").arg(value):"",
|
||||||
|
mTokenizer[mIndex]->line,
|
||||||
|
StatementKind::skEnum,
|
||||||
|
getScope(),
|
||||||
|
mCurrentMemberAccessibility,
|
||||||
|
StatementProperty::spHasDefinition);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QString strValue=canCalcValue?QString("%1").arg(value):"";
|
||||||
|
if (enumStatement) {
|
||||||
|
addStatement(
|
||||||
|
enumStatement,
|
||||||
|
mCurrentFile,
|
||||||
|
lastType,
|
||||||
|
cmd,
|
||||||
|
args,
|
||||||
|
"",
|
||||||
|
strValue,
|
||||||
|
mTokenizer[mIndex]->line,
|
||||||
|
StatementKind::skEnum,
|
||||||
|
getScope(),
|
||||||
|
mCurrentMemberAccessibility,
|
||||||
|
StatementProperty::spHasDefinition);
|
||||||
|
}
|
||||||
|
addStatement(
|
||||||
|
getCurrentScope(),
|
||||||
|
mCurrentFile,
|
||||||
|
lastType,
|
||||||
|
cmd,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
strValue,
|
||||||
|
mTokenizer[mIndex]->line,
|
||||||
|
StatementKind::skEnum,
|
||||||
|
getScope(),
|
||||||
|
mCurrentMemberAccessibility,
|
||||||
|
StatementProperty::spHasDefinition);
|
||||||
|
}
|
||||||
|
value++;
|
||||||
}
|
}
|
||||||
|
mIndex ++ ;
|
||||||
}
|
}
|
||||||
if (mIndex<endIndex)
|
if (mIndex<endIndex)
|
||||||
mIndex=endIndex;
|
mIndex=endIndex;
|
||||||
|
@ -3474,6 +3703,7 @@ void CppParser::handleStructs(bool isTypedef)
|
||||||
PStatement scopeStatement=getCurrentScope();
|
PStatement scopeStatement=getCurrentScope();
|
||||||
QString scopelessName;
|
QString scopelessName;
|
||||||
QString parentName;
|
QString parentName;
|
||||||
|
|
||||||
if (splitLastMember(command,scopelessName,parentName)) {
|
if (splitLastMember(command,scopelessName,parentName)) {
|
||||||
scopeStatement = getIncompleteClass(parentName,getCurrentScope());
|
scopeStatement = getIncompleteClass(parentName,getCurrentScope());
|
||||||
} else {
|
} else {
|
||||||
|
@ -3580,7 +3810,7 @@ void CppParser::handleStructs(bool isTypedef)
|
||||||
getCurrentScope(),
|
getCurrentScope(),
|
||||||
mCurrentFile,
|
mCurrentFile,
|
||||||
prefix,
|
prefix,
|
||||||
"__"+command,
|
"_@dummy@_"+command,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -3589,7 +3819,7 @@ void CppParser::handleStructs(bool isTypedef)
|
||||||
StatementKind::skClass,
|
StatementKind::skClass,
|
||||||
getScope(),
|
getScope(),
|
||||||
mCurrentMemberAccessibility,
|
mCurrentMemberAccessibility,
|
||||||
StatementProperty::spHasDefinition);
|
StatementProperty::spHasDefinition | StatementProperty::spDummyStatement);
|
||||||
}
|
}
|
||||||
if (isTypedef) {
|
if (isTypedef) {
|
||||||
//typedef
|
//typedef
|
||||||
|
|
|
@ -216,6 +216,12 @@ private:
|
||||||
|
|
||||||
QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
|
QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
|
||||||
|
|
||||||
|
int evaluateConstExpr(int endIndex, bool &ok);
|
||||||
|
int evaluateAdditionConstExpr(int endIndex, bool &ok);
|
||||||
|
int evaluateMultiplyConstExpr(int endIndex, bool &ok);
|
||||||
|
int evaluateConstExprTerm(int endIndex, bool &ok);
|
||||||
|
int evaluateLiteralNumber(int endIndex, bool &ok);
|
||||||
|
|
||||||
bool checkForKeyword(KeywordType &keywordType);
|
bool checkForKeyword(KeywordType &keywordType);
|
||||||
bool checkForNamespace(KeywordType keywordType);
|
bool checkForNamespace(KeywordType keywordType);
|
||||||
bool checkForPreprocessor();
|
bool checkForPreprocessor();
|
||||||
|
|
|
@ -153,7 +153,8 @@ enum StatementProperty {
|
||||||
spOverride = 0x0040,
|
spOverride = 0x0040,
|
||||||
spConstexpr = 0x0080,
|
spConstexpr = 0x0080,
|
||||||
spFunctionPointer = 0x0100,
|
spFunctionPointer = 0x0100,
|
||||||
spOperatorOverloading = 0x0200
|
spOperatorOverloading = 0x0200,
|
||||||
|
spDummyStatement = 0x0400
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(StatementProperties, StatementProperty)
|
Q_DECLARE_FLAGS(StatementProperties, StatementProperty)
|
||||||
|
|
|
@ -148,12 +148,18 @@ QVariant ClassBrowserModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant();
|
return QVariant();
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
if (node->statement) {
|
if (node->statement) {
|
||||||
if (!(node->statement->type.isEmpty()) &&
|
if (!(node->statement->type.isEmpty())) {
|
||||||
((node->statement->kind == StatementKind::skFunction)
|
if ((node->statement->kind == StatementKind::skFunction)
|
||||||
|| (node->statement->kind == StatementKind::skVariable)
|
|| (node->statement->kind == StatementKind::skVariable)
|
||||||
|| (node->statement->kind == StatementKind::skTypedef)
|
|| (node->statement->kind == StatementKind::skTypedef)
|
||||||
)) {
|
) {
|
||||||
return node->statement->command + node->statement->args + " : " + node->statement->type;
|
return node->statement->command + node->statement->args + " : " + node->statement->type;
|
||||||
|
} else if (node->statement->kind == StatementKind::skEnum) {
|
||||||
|
if (!node->statement->value.isEmpty())
|
||||||
|
return node->statement->command + node->statement->args + QString("(%1)").arg(node->statement->value);
|
||||||
|
else
|
||||||
|
return node->statement->command;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return node->statement->command + node->statement->args;
|
return node->statement->command + node->statement->args;
|
||||||
}
|
}
|
||||||
|
@ -351,9 +357,12 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa
|
||||||
|
|
||||||
if (mProcessedStatements.contains(statement.get()))
|
if (mProcessedStatements.contains(statement.get()))
|
||||||
continue;
|
continue;
|
||||||
|
// if (statement->properties.testFlag(StatementProperty::spDummyStatement))
|
||||||
|
// continue;
|
||||||
|
|
||||||
if (statement->kind == StatementKind::skBlock)
|
if (statement->kind == StatementKind::skBlock)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (statement->isInherited() && !pSettings->ui().classBrowserShowInherited())
|
if (statement->isInherited() && !pSettings->ui().classBrowserShowInherited())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,9 @@ void CodeCompletionPopup::addStatement(const PStatement& statement, const QStrin
|
||||||
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))
|
|| statement->properties.testFlag(StatementProperty::spOperatorOverloading)
|
||||||
|
|| statement->properties.testFlag(StatementProperty::spDummyStatement)
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
if ((line!=-1)
|
if ((line!=-1)
|
||||||
&& (line < statement->line)
|
&& (line < statement->line)
|
||||||
|
|
Loading…
Reference in New Issue