work save

This commit is contained in:
Roy Qu 2022-11-04 20:27:35 +08:00
parent 20917e3a8b
commit 585d7678d4
8 changed files with 531 additions and 326 deletions

View File

@ -4,6 +4,7 @@ Red Panda C++ Version 2.2
- enhancement: slightly reduce parsing time - enhancement: slightly reduce parsing time
- fix: Wrong charset name returned when saveing file - fix: Wrong charset name returned when saveing file
- fix: 'using =' / 'namespace =' not correctly handled - fix: 'using =' / 'namespace =' not correctly handled
- fix: Pressing '*' at begin of line will crash app
Red Panda C++ Version 2.1 Red Panda C++ Version 2.1

View File

@ -2338,7 +2338,7 @@ bool Editor::handleBracketSkip()
bool Editor::handleMultilineCommentCompletion() bool Editor::handleMultilineCommentCompletion()
{ {
if ((caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) { if ((caretX()-2>=0) && (caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) {
QString text=selText(); QString text=selText();
beginUpdate(); beginUpdate();
beginUndoBlock(); beginUndoBlock();

View File

@ -1275,6 +1275,7 @@ PStatement CppParser::addStatement(const PStatement& parent,
PStatement CppParser::addStatement(const PStatement &parent, const QString &fileName, const QString &aType, const QString &command, int argStart, int argEnd, const QString &value, int line, StatementKind kind, const StatementScope &scope, const StatementClassScope &classScope, bool isDefinition, bool isStatic) PStatement CppParser::addStatement(const PStatement &parent, const QString &fileName, const QString &aType, const QString &command, int argStart, int argEnd, const QString &value, int line, StatementKind kind, const StatementScope &scope, const StatementClassScope &classScope, bool isDefinition, bool isStatic)
{ {
Q_ASSERT(mTokenizer[argStart]->text=='(');
QString args("("); QString args("(");
QString noNameArgs("("); QString noNameArgs("(");
@ -1284,7 +1285,7 @@ PStatement CppParser::addStatement(const PStatement &parent, const QString &file
QString word; QString word;
for (int i=start;i<argEnd;i++) { for (int i=start;i<argEnd;i++) {
QChar ch=mTokenizer[i]->text[0]; QChar ch=mTokenizer[i]->text[0];
if (this->isLetterChar(ch)) { if (this->isIdentChar(ch)) {
QString spaces=(i>argStart)?" ":""; QString spaces=(i>argStart)?" ":"";
args+=spaces; args+=spaces;
word += mTokenizer[i]->text[0]; word += mTokenizer[i]->text[0];
@ -1556,11 +1557,10 @@ QStringList CppParser::sortFilesByIncludeRelations(const QSet<QString> &files)
bool CppParser::checkForKeyword(KeywordType& keywordType) bool CppParser::checkForKeyword(KeywordType& keywordType)
{ {
keywordType = mCppKeywords.value(mTokenizer[mIndex]->text,KeywordType::None); keywordType = mCppKeywords.value(mTokenizer[mIndex]->text,KeywordType::NotKeyword);
switch(keywordType) { switch(keywordType) {
case KeywordType::Catch: case KeywordType::Catch:
case KeywordType::For: case KeywordType::For:
case KeywordType::None:
case KeywordType::Public: case KeywordType::Public:
case KeywordType::Private: case KeywordType::Private:
case KeywordType::Enum: case KeywordType::Enum:
@ -1570,6 +1570,8 @@ bool CppParser::checkForKeyword(KeywordType& keywordType)
case KeywordType::Using: case KeywordType::Using:
case KeywordType::Friend: case KeywordType::Friend:
case KeywordType::Protected: case KeywordType::Protected:
case KeywordType::None:
case KeywordType::NotKeyword:
return false; return false;
default: default:
return true; return true;
@ -1625,13 +1627,13 @@ bool CppParser::checkForMethod(QString &sType, QString &sName, int &argStartInde
if (currentScope) { if (currentScope) {
//in namespace, it might be function or object initilization //in namespace, it might be function or object initilization
if (currentScope->kind == StatementKind::skNamespace if (currentScope->kind == StatementKind::skNamespace
&& isNotFuncArgs(mIndex + 1,mTokenizer[mIndex + 1]->matchIndex)) { && isNotFuncArgs(mIndex + 1)) {
break; break;
//not in class, it can't be a valid function definition //not in class, it can't be a valid function definition
} else if (currentScope->kind != StatementKind::skClass) } else if (currentScope->kind != StatementKind::skClass)
break; break;
//variable can't be initialized in class definition, it must be a function //variable can't be initialized in class definition, it must be a function
} else if (isNotFuncArgs(mIndex + 1,mTokenizer[mIndex + 1]->matchIndex)) } else if (isNotFuncArgs(mIndex + 1))
break; break;
} }
sName = mTokenizer[mIndex]->text; sName = mTokenizer[mIndex]->text;
@ -1708,12 +1710,12 @@ bool CppParser::checkForPreprocessor()
return (mTokenizer[mIndex]->text.startsWith('#')); return (mTokenizer[mIndex]->text.startsWith('#'));
} }
bool CppParser::checkForLambda() //bool CppParser::checkForLambda()
{ //{
return (mIndex+1<mTokenizer.tokenCount() // return (mIndex+1<mTokenizer.tokenCount()
&& mTokenizer[mIndex]->text.startsWith('[') // && mTokenizer[mIndex]->text.startsWith('[')
&& mTokenizer[mIndex+1]->text=='('); // && mTokenizer[mIndex+1]->text=='(');
} //}
bool CppParser::checkForScope(KeywordType keywordType) bool CppParser::checkForScope(KeywordType keywordType)
{ {
@ -1727,13 +1729,7 @@ bool CppParser::checkForScope(KeywordType keywordType)
void CppParser::checkForSkipStatement() void CppParser::checkForSkipStatement()
{ {
if ((mSkipList.count()>0) && (mIndex == mSkipList.back())) { // skip to next ';' if ((mSkipList.count()>0) && (mIndex == mSkipList.back())) { // skip to next ';'
do { skipNextSemicolon(mIndex);
if (isLeftParenthesis(mTokenizer[mIndex]->text))
mIndex=mTokenizer[mIndex]->matchIndex+1;
else
mIndex++;
} while ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text[0] != ';'));
mIndex++; //skip ';'
mSkipList.pop_back(); mSkipList.pop_back();
} }
} }
@ -1819,6 +1815,189 @@ bool CppParser::checkForUsing(KeywordType keywordType)
} }
void CppParser::checkAndHandleMethodOrVar()
{
if (mIndex+2>=mTokenizer.tokenCount()) {
mIndex+=2; // left's finish;
return;
}
QString currentText=mTokenizer[mIndex]->text;
mIndex++;
//next token must be */&/word/(/{
if (mTokenizer[mIndex]->text=='(') {
int indexAfterParentheis=mTokenizer[mIndex]->matchIndex+1;
if (indexAfterParentheis>=mTokenizer.tokenCount()) {
//error
mIndex=indexAfterParentheis;
} else if (mTokenizer[indexAfterParentheis]->text=='(') {
// operator overloading like (operator int)
if (mTokenizer[mIndex+1]->text=="operator") {
mIndex=indexAfterParentheis;
handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false);
} else if (currentText.endsWith("::operator")) {
mIndex=indexAfterParentheis;
handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false);
} else {
//function pointer var
handleVar(currentText,false,false);
}
} else {
if (currentText.startsWith("operator")
&& currentText.length()>8
&& !isIdentChar(currentText[8])) {
// operator overloading
handleMethod(StatementKind::skFunction,"",
mergeArgs(mIndex+1,mTokenizer[mIndex]->matchIndex-1),
indexAfterParentheis,false,false);
return;
}
//check for constructor like Foo::Foo()
QString name;
QString temp,temp2;
QString parentName;
if (splitLastMember(currentText,name,temp)) {
//has '::'
bool isDestructor=false;
if (!splitLastMember(temp,parentName,temp2))
parentName=temp;
if (name.startsWith('~'))
name=name.mid(1);
if (removeTemplateParams(name)==removeTemplateParams(parentName))
handleMethod( (isDestructor?StatementKind::skDestructor:StatementKind::skConstructor),
"",
currentText,
mIndex,false,false);
return;
}
// check for constructor like:
// class Foo {
// Foo();
// };
PStatement scope=getCurrentScope();
if (scope && scope->kind==StatementKind::skClass
&& removeTemplateParams(scope->command) == removeTemplateParams(currentText)) {
handleMethod(StatementKind::skConstructor,"",
currentText,
mIndex,false,false);
return;
}
// function call, skip it
skipNextSemicolon(mIndex);
}
} else if (mTokenizer[mIndex]->text.startsWith('*')
|| mTokenizer[mIndex]->text.startsWith('&')
|| tokenIsIdentifier(mTokenizer[mIndex]->text)
) {
// it should be function/var
bool isStatic = false;
bool isFriend = false;
bool isExtern = false;
QString sType = currentText; // should contain type "int"
QString sName = ""; // should contain function name "foo::function"
// Gather data for the string parts
while (mIndex+1 < mTokenizer.tokenCount()) {
if (mTokenizer[mIndex + 1]->text == '(') {
if (mTokenizer[mIndex+2]->text == '*') {
//foo(*blabla), it's a function pointer var
handleVar(sType,isExtern,isStatic);
return;
}
int indexAfter=mTokenizer[mIndex + 1]->matchIndex+1;
if (indexAfter>=mTokenizer.tokenCount()) {
//error
mIndex=indexAfter;
return;
}
//if it's like: foo(...)(...)
if (mTokenizer[indexAfter]->text=='(') {
if (mTokenizer[mIndex]->text=="operator") {
//operator()() , it's an operator overload for ()
handleMethod(StatementKind::skFunction,sType,
"operator()",indexAfter,isStatic,false);
return;
}
if (mTokenizer[mIndex]->text.endsWith("::operator")) {
// operator overloading
handleMethod(StatementKind::skFunction,"",
mTokenizer[mIndex]->text+"()",indexAfter,isStatic,false);
return;
}
//foo(...)(...), it's a function pointer var
handleVar(sType,isExtern,isStatic);
//Won't implement: ignore function decl like int (text)(int x) { };
return;
}
//it's not a function define
if (mTokenizer[indexAfter]->text[0] == ',') {
// var decl with init
handleVar(sType,isExtern,isStatic);
return;
}
if (mTokenizer[indexAfter]->text[0] == ';') {
//function can only be defined in global/namespaces/classes
PStatement currentScope=getCurrentScope();
if (currentScope) {
//in namespace, it might be function or object initilization
if (currentScope->kind == StatementKind::skNamespace
&& isNotFuncArgs(mIndex + 1)) {
// var decl with init
handleVar(sType,isExtern,isStatic);
return;
//not in class, it can't be a valid function definition
} else if (currentScope->kind != StatementKind::skClass) {
// var decl with init
handleVar(sType,isExtern,isStatic);
return;
}
//variable can't be initialized in class definition, it must be a function
} else if (isNotFuncArgs(mIndex + 1)){
// var decl with init
handleVar(sType,isExtern,isStatic);
return;
}
}
sName = mTokenizer[mIndex]->text;
mIndex++;
handleMethod(StatementKind::skFunction,sType,
sName,mIndex,isStatic,isFriend);
return;
} else if (
mTokenizer[mIndex + 1]->text == ','
||mTokenizer[mIndex + 1]->text == ';'
||mTokenizer[mIndex + 1]->text == ':'
||mTokenizer[mIndex + 1]->text == '{') {
handleVar(sType,isExtern,isStatic);
return;
} else {
QString s = mTokenizer[mIndex]->text;
if (s == "static")
isStatic = true;
else if (s == "friend")
isFriend = true;
else if (s == "extern")
isExtern = true;
if (!s.isEmpty() && !(s=="extern"))
sType = sType + ' '+ s;
mIndex++;
}
}
}
}
int CppParser::getCurrentBlockEndSkip() int CppParser::getCurrentBlockEndSkip()
{ {
if (mBlockEndSkips.isEmpty()) if (mBlockEndSkips.isEmpty())
@ -2232,23 +2411,23 @@ void CppParser::handleKeyword(KeywordType skipType)
// skip it; // skip it;
mIndex++; mIndex++;
break; break;
case KeywordType::SkipAfterSemicolon: case KeywordType::SkipNextSemicolon:
// Skip to ; and over it // Skip to ; and over it
mIndex = indexOfNextSemicolon(mIndex)+1; skipNextSemicolon(mIndex);
break; break;
case KeywordType::SkipAfterColon: case KeywordType::SkipNextColon:
// Skip to : and over it // Skip to : and over it
mIndex = indexOfNextColon(mIndex)+1; mIndex = indexOfNextColon(mIndex)+1;
break; break;
case KeywordType::SkipAfterParenthesis: case KeywordType::SkipNextParenthesis:
// skip pass () // skip pass ()
mIndex = indexPassParenthesis(mIndex); skipParenthesis(mIndex);
break; break;
case KeywordType::SkipToLeftBrace: case KeywordType::MoveToLeftBrace:
// Skip to { // Skip to {
mIndex = indexOfNextLeftBrace(mIndex); mIndex = indexOfNextLeftBrace(mIndex);
break; break;
case KeywordType::SkipAfterBrace: case KeywordType::MoveToRightBrace:
// Skip pass {} // Skip pass {}
mIndex = indexPassBraces(mIndex); mIndex = indexPassBraces(mIndex);
break; break;
@ -2288,19 +2467,21 @@ void CppParser::handleLambda()
mIndex=bodyStart+1; // skip '{' mIndex=bodyStart+1; // skip '{'
} }
void CppParser::handleMethod(const QString &sType, const QString &sName, int argStart, int argEnd, bool isStatic, bool isFriend) void CppParser::handleMethod(StatementKind functionKind,const QString &sType, const QString &sName, int argStart, bool isStatic, bool isFriend)
{ {
bool isValid = true; bool isValid = true;
bool isDeclaration = false; // assume it's not a prototype bool isDeclaration = false; // assume it's not a prototype
int startLine = mTokenizer[mIndex]->line; int startLine = mTokenizer[mIndex]->line;
int argEnd = mTokenizer[argStart]->matchIndex;
if (mIndex >= mTokenizer.tokenCount()) // not finished define, just skip it; if (mIndex >= mTokenizer.tokenCount()) // not finished define, just skip it;
return; return;
PStatement functionClass = getCurrentScope(); PStatement scopeStatement = getCurrentScope();
//find start of the function body; //find start of the function body;
bool foundColon=false; bool foundColon=false;
mIndex=argEnd+1;
while ((mIndex < mTokenizer.tokenCount()) && !isblockChar(mTokenizer[mIndex]->text.front())) { while ((mIndex < mTokenizer.tokenCount()) && !isblockChar(mTokenizer[mIndex]->text.front())) {
if (mTokenizer[mIndex]->text=='(') { if (mTokenizer[mIndex]->text=='(') {
mIndex=mTokenizer[mIndex]->matchIndex+1; mIndex=mTokenizer[mIndex]->matchIndex+1;
@ -2335,17 +2516,17 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
QString scopelessName; QString scopelessName;
PStatement functionStatement; PStatement functionStatement;
if (isFriend && isDeclaration && functionClass) { if (isFriend && isDeclaration && scopeStatement) {
int delimPos = sName.indexOf("::"); int delimPos = sName.indexOf("::");
if (delimPos >= 0) { if (delimPos >= 0) {
scopelessName = sName.mid(delimPos+2); scopelessName = sName.mid(delimPos+2);
} else } else
scopelessName = sName; scopelessName = sName;
//TODO : we should check namespace //TODO : we should check namespace
functionClass->friends.insert(scopelessName); scopeStatement->friends.insert(scopelessName);
} else if (isValid) { } else if (isValid) {
// Use the class the function belongs to as the parent ID if the function is declared outside of the class body // Use the class the function belongs to as the parent ID if the function is declared outside of the class body
int delimPos = sName.indexOf("::"); int delimPos = sName.lastIndexOf("::");
QString scopelessName; QString scopelessName;
QString parentClassName; QString parentClassName;
if (delimPos >= 0) { if (delimPos >= 0) {
@ -2354,24 +2535,15 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
// Check what class this function belongs to // Check what class this function belongs to
parentClassName = sName.mid(0, delimPos); parentClassName = sName.mid(0, delimPos);
functionClass = getIncompleteClass(parentClassName,getCurrentScope()); scopeStatement = getIncompleteClass(parentClassName,getCurrentScope());
} else } else
scopelessName = sName; scopelessName = sName;
StatementKind functionKind;
// Determine function type
if (scopelessName == sType) {
functionKind = StatementKind::skConstructor;
} else if (scopelessName == '~' + sType) {
functionKind = StatementKind::skDestructor;
} else {
functionKind = StatementKind::skFunction;
}
// For function definitions, the parent class is given. Only use that as a parent // For function definitions, the parent class is given. Only use that as a parent
if (!isDeclaration) { if (!isDeclaration) {
functionStatement=addStatement( functionStatement=addStatement(
functionClass, scopeStatement,
mCurrentFile, mCurrentFile,
sType, sType,
scopelessName, scopelessName,
@ -2387,13 +2559,13 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
isStatic); isStatic);
scanMethodArgs(functionStatement, argStart,argEnd); scanMethodArgs(functionStatement, argStart,argEnd);
// add variable this to the class function // add variable this to the class function
if (functionClass && functionClass->kind == StatementKind::skClass && if (scopeStatement && scopeStatement->kind == StatementKind::skClass &&
!isStatic) { !isStatic) {
//add this to non-static class member function //add this to non-static class member function
addStatement( addStatement(
functionStatement, functionStatement,
mCurrentFile, mCurrentFile,
functionClass->command, scopeStatement->command+"*",
"this", "this",
"", "",
"", "",
@ -2405,6 +2577,7 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
true, true,
false); false);
} }
// add "__func__ variable" // add "__func__ variable"
addStatement( addStatement(
functionStatement, functionStatement,
@ -2420,9 +2593,10 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
StatementClassScope::None, StatementClassScope::None,
true, true,
false); false);
} else { } else {
functionStatement = addStatement( functionStatement = addStatement(
functionClass, scopeStatement,
mCurrentFile, mCurrentFile,
sType, sType,
scopelessName, scopelessName,
@ -2440,7 +2614,6 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
} }
if ((mIndex < mTokenizer.tokenCount()) && mTokenizer[mIndex]->text.startsWith('{')) { if ((mIndex < mTokenizer.tokenCount()) && mTokenizer[mIndex]->text.startsWith('{')) {
addSoloScopeLevel(functionStatement,startLine); addSoloScopeLevel(functionStatement,startLine);
mIndex++; //skip '{' mIndex++; //skip '{'
@ -2452,7 +2625,6 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, int arg
removeScopeLevel(startLine+1); removeScopeLevel(startLine+1);
mIndex++; mIndex++;
} }
} }
void CppParser::handleNamespace(KeywordType skipType) void CppParser::handleNamespace(KeywordType skipType)
@ -2467,9 +2639,9 @@ void CppParser::handleNamespace(KeywordType skipType)
mIndex++; //skip 'namespace' mIndex++; //skip 'namespace'
if (!isLetterChar(mTokenizer[mIndex]->text.front())) // if (!tokenIsIdentifier(mTokenizer[mIndex]->text))
//wrong namespace define, stop handling // //wrong namespace define, stop handling
return; // return;
QString command = mTokenizer[mIndex]->text; QString command = mTokenizer[mIndex]->text;
QString fullName = getFullStatementName(command,getCurrentScope()); QString fullName = getFullStatementName(command,getCurrentScope());
@ -2747,8 +2919,6 @@ void CppParser::handleScope(KeywordType keywordType)
bool CppParser::handleStatement() bool CppParser::handleStatement()
{ {
QString funcType,funcName; QString funcType,funcName;
int argStart,argEnd;
bool isStatic, isFriend;
int idx=getCurrentBlockEndSkip(); int idx=getCurrentBlockEndSkip();
int idx2=getCurrentBlockBeginSkip(); int idx2=getCurrentBlockBeginSkip();
int idx3=getCurrentInlineNamespaceEndSkip(); int idx3=getCurrentInlineNamespaceEndSkip();
@ -2796,10 +2966,30 @@ bool CppParser::handleStatement()
mIndex++; mIndex++;
} else if (checkForPreprocessor()) { } else if (checkForPreprocessor()) {
handlePreprocessor(); handlePreprocessor();
} else if (checkForLambda()) { // is lambda // } else if (checkForLambda()) { // is lambda
handleLambda(); // handleLambda();
} else if (!isLetterChar(mTokenizer[mIndex]->text[0])) { } else if (mTokenizer[mIndex]->text=='(') {
if (mTokenizer[mIndex]->text=="operator") {
// things like (operator int)
mIndex++; //just skip '('
} else
skipParenthesis(mIndex);
} else if (mTokenizer[mIndex]->text==')') {
mIndex++; mIndex++;
} else if (mTokenizer[mIndex]->text.startsWith('~')) {
//it should be a destructor
if (mIndex+1<mTokenizer.tokenCount()
&& mTokenizer[mIndex+1]->text=='(') {
//dont further check to speed up
handleMethod(StatementKind::skDestructor, "", '~'+mTokenizer[mIndex]->text, mIndex+1, false, false);
} else {
skipNextSemicolon(mIndex);
}
} else if (!isIdentChar(mTokenizer[mIndex]->text[0])) {
skipNextSemicolon(mIndex);
} else if (mTokenizer[mIndex]->text.endsWith('.')
|| mTokenizer[mIndex]->text.endsWith("->")) {
skipNextSemicolon(mIndex);
} else if (checkForKeyword(keywordType)) { // includes template now } else if (checkForKeyword(keywordType)) { // includes template now
handleKeyword(keywordType); handleKeyword(keywordType);
} else if (keywordType==KeywordType::For) { // (for/catch) } else if (keywordType==KeywordType::For) { // (for/catch)
@ -2828,13 +3018,19 @@ bool CppParser::handleStatement()
handleUsing(); handleUsing();
} else if (checkForStructs(keywordType)) { } else if (checkForStructs(keywordType)) {
handleStructs(false); handleStructs(false);
} else if (checkForMethod(funcType, funcName, argStart,argEnd, isStatic, isFriend)) { } else {
handleMethod(funcType, funcName, argStart, argEnd, isStatic, isFriend); // don't recalculate parts // it should be method/constructor/var
} else if (tryHandleVar()) { checkAndHandleMethodOrVar();
//do nothing }
} else Q_ASSERT(mIndex<999999);
mIndex++; // else if (checkForMethod(funcType, funcName, argStart,argEnd, isStatic, isFriend)) {
// handleMethod(funcType, funcName, argStart, argEnd, isStatic, isFriend); // don't recalculate parts
// } else if (tryHandleVar()) {
// //do nothing
// } else
// mIndex++;
//todo: remove mSkipList (we can check '}''s statement type instead)
checkForSkipStatement(); checkForSkipStatement();
return mIndex < mTokenizer.tokenCount(); return mIndex < mTokenizer.tokenCount();
@ -2947,6 +3143,7 @@ void CppParser::handleStructs(bool isTypedef)
command = ""; command = "";
} }
mIndex++; mIndex++;
break;
} else if ((mIndex + 2 < mTokenizer.tokenCount()) } else if ((mIndex + 2 < mTokenizer.tokenCount())
&& (mTokenizer[mIndex + 1]->text == "final") && (mTokenizer[mIndex + 1]->text == "final")
&& (mTokenizer[mIndex + 2]->text.front()==',' && (mTokenizer[mIndex + 2]->text.front()==','
@ -2971,6 +3168,7 @@ void CppParser::handleStructs(bool isTypedef)
command=""; command="";
} }
mIndex+=2; mIndex+=2;
break;
} else } else
mIndex++; mIndex++;
} }
@ -2980,8 +3178,7 @@ void CppParser::handleStructs(bool isTypedef)
if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() == ':')) { if ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() == ':')) {
if (firstSynonym) if (firstSynonym)
setInheritance(mIndex, firstSynonym, isStruct); // set the _InheritanceList value setInheritance(mIndex, firstSynonym, isStruct); // set the _InheritanceList value
while ((mIndex < mTokenizer.tokenCount()) && (mTokenizer[mIndex]->text.front() != '{')) mIndex=indexOfNextLeftBrace(mIndex);
mIndex++; // skip decl after ':'
} }
// Check for struct synonyms after close brace // Check for struct synonyms after close brace
@ -3087,7 +3284,7 @@ void CppParser::handleStructs(bool isTypedef)
} }
} }
if (!firstSynonym) { if (!firstSynonym) {
//anonymous union/struct/class, add ast a block //anonymous union/struct/class, add as a block
firstSynonym=addStatement( firstSynonym=addStatement(
getCurrentScope(), getCurrentScope(),
mCurrentFile, mCurrentFile,
@ -3201,77 +3398,65 @@ void CppParser::handleUsing()
} }
} }
bool CppParser::tryHandleVar() void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
{ {
int indexBackup=mIndex;
KeywordType keywordType;
QString varType=mTokenizer[mIndex]->text;
bool isExtern = false;
bool isStatic = false;
QString lastType; QString lastType;
if (isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front()) if (typePrefix=="extern") {
|| mTokenizer[mIndex]->text.endsWith('.')
|| mTokenizer[mIndex]->text.endsWith("->"))
//failed to handle
return false;
if (varType=="extern") {
isExtern=true; isExtern=true;
} else if (varType=="static") { } else if (typePrefix=="static") {
isStatic=true; isStatic=true;
} else { } else {
lastType=varType; lastType=typePrefix;
} }
mIndex++;
//we only check the first token to reduce calculations //we only check the first token to reduce calculations
if (mIndex>=mTokenizer.tokenCount() // if (mIndex>=mTokenizer.tokenCount()
|| checkForKeyword(keywordType) // || mTokenizer[mIndex]->text.endsWith('.')
|| isInvalidVarPrefixChar(mTokenizer[mIndex]->text.front()) // || mTokenizer[mIndex]->text.endsWith("->")) {
|| mTokenizer[mIndex]->text.endsWith('.') // //failed to handle
|| mTokenizer[mIndex]->text.endsWith("->")) { // skipNextSemicolon(mIndex);
//failed to handle // return ;
mIndex=indexBackup; // }
return false;
}
while (mIndex+1<mTokenizer.tokenCount()) { // while (mIndex+1<mTokenizer.tokenCount()) {
if (mTokenizer[mIndex]->text=='(') { // if (mTokenizer[mIndex]->text=='(') {
if ( mTokenizer[mIndex]->matchIndex<=mTokenizer.tokenCount() // if ( mTokenizer[mIndex]->matchIndex<=mTokenizer.tokenCount()
&& mTokenizer[mTokenizer[mIndex]->matchIndex]->text=='(') { // && mTokenizer[mTokenizer[mIndex]->matchIndex]->text=='(') {
//function pointer // //function pointer
break; // break;
} // }
//error break; // //error break;
mIndex=indexBackup; // mIndex=indexBackup;
return false; // return false;
} else if (mTokenizer[mIndex + 1]->text=='(' // } else if (mTokenizer[mIndex + 1]->text=='('
|| mTokenizer[mIndex + 1]->text==',' // || mTokenizer[mIndex + 1]->text==','
|| mTokenizer[mIndex + 1]->text==';' // || mTokenizer[mIndex + 1]->text==';'
|| mTokenizer[mIndex + 1]->text.front()==':' // || mTokenizer[mIndex + 1]->text.front()==':'
|| mTokenizer[mIndex + 1]->text=='}' // || mTokenizer[mIndex + 1]->text=='}'
|| mTokenizer[mIndex + 1]->text.front()=='#' // || mTokenizer[mIndex + 1]->text.front()=='#'
|| mTokenizer[mIndex + 1]->text=='{') { // || mTokenizer[mIndex + 1]->text=='{') {
//end of type info // //end of type info
break; // break;
} else if (mTokenizer[mIndex]->text!="struct" // } else if (mTokenizer[mIndex]->text!="struct"
&& mTokenizer[mIndex]->text!="class" // && mTokenizer[mIndex]->text!="class"
&& mTokenizer[mIndex]->text!="union") { // && mTokenizer[mIndex]->text!="union") {
QString s=mTokenizer[mIndex]->text; // QString s=mTokenizer[mIndex]->text;
if (s == "extern") { // if (s == "extern") {
isExtern = true; // isExtern = true;
} else if (s == "static") { // } else if (s == "static") {
isStatic = true; // isStatic = true;
} else // } else
lastType += ' '+s; // lastType += ' '+s;
} // }
mIndex++; // mIndex++;
} // }
if (mIndex+1 >= mTokenizer.tokenCount() || lastType.isEmpty() // if (mIndex+1 >= mTokenizer.tokenCount() || lastType.isEmpty()
|| lastType.endsWith(':')) { // || lastType.endsWith(':')) {
mIndex=indexBackup; // mIndex=indexBackup;
return false; // return false;
} // }
bool varAdded = false; bool varAdded = false;
QString tempType; QString tempType;
@ -3365,8 +3550,6 @@ bool CppParser::tryHandleVar()
} }
// Skip ; // Skip ;
mIndex++; mIndex++;
return true;
} }
void CppParser::internalParse(const QString &fileName) void CppParser::internalParse(const QString &fileName)
@ -4505,6 +4688,8 @@ void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart
} }
} }
} else { } else {
if (!varType.isEmpty())
varType+=' ';
varType+=cmd; varType+=cmd;
} }
i++; i++;
@ -4585,118 +4770,49 @@ QString CppParser::splitPhrase(const QString &phrase, QString &sClazz,
return result; return result;
} }
QString CppParser::removeTemplateParams(const QString &phrase)
{
int pos = phrase.indexOf('<');
if (pos>=0) {
return phrase.left(pos);
}
return phrase;
}
bool CppParser::splitLastMember(const QString &token, QString &lastMember, QString &remaining)
{
int pos = token.lastIndexOf("::");
if (pos<0)
return false;
lastMember=token.mid(pos+2);
remaining=token.left(pos);
return true;
}
static bool isIdentChar(const QChar& ch) { static bool isIdentChar(const QChar& ch) {
return ch.isLetter() return ch.isLetter()
|| ch == '_' || ch == '_'
|| ch.isDigit(); || ch.isDigit();
} }
static void appendArgWord(QString& args, const QString& word) { //static void appendArgWord(QString& args, const QString& word) {
QString s=word.trimmed(); // QString s=word.trimmed();
if (s.isEmpty()) // if (s.isEmpty())
return; // return;
if (args.isEmpty()) // if (args.isEmpty())
args.append(s); // args.append(s);
else if (isIdentChar(args.back()) && isIdentChar(word.front()) ) { // else if (isIdentChar(args.back()) && isIdentChar(word.front()) ) {
args+=" "; // args+=" ";
args+=s; // args+=s;
} else { // } else {
args+=s; // args+=s;
} // }
} //}
QString CppParser::removeArgNames(const QString &args)
{
QString result = "";
int argsLen = args.length();
if (argsLen < 2)
return "";
int i=1; // skip start '('
QString currentArg;
QString word;
int brackLevel = 0;
bool typeGetted = false;
while (i<argsLen-1) { //skip end ')'
switch(args[i].unicode()) {
case ',':
if (brackLevel >0) {
word+=args[i];
} else {
if (!typeGetted) {
appendArgWord(currentArg,word);
} else {
if (isCppKeyword(word)) {
appendArgWord(currentArg,word);
}
}
word = "";
result += currentArg.trimmed() + ',';
currentArg = "";
typeGetted = false;
}
break;
case '<':
case '[':
case '(':
brackLevel++;
word+=args[i];
break;
case '>':
case ']':
case ')':
brackLevel--;
word+=args[i];
break;
case ' ':
case '\t':
if ((brackLevel >0) && !isSpaceChar(args[i-1])) {
word+=args[i];
} else if (!word.isEmpty()) {
if (!typeGetted) {
appendArgWord(currentArg,word);
if (mCppTypeKeywords.contains(word) || !isCppKeyword(word))
typeGetted = true;
} else {
if (isCppKeyword(word))
appendArgWord(currentArg,word);
}
word = "";
}
break;
case '&':
case '*':
if (!word.isEmpty()) {
if (!typeGetted) {
appendArgWord(currentArg,word);
if (mCppTypeKeywords.contains(word) || !isCppKeyword(word))
typeGetted = true;
} else {
if (isCppKeyword(word))
appendArgWord(currentArg,word);
}
word = "";
}
currentArg+=args[i];
break;
default:
if (isIdentChar(args[i])) {
word+=args[i];
}
}
i++;
}
if (!typeGetted) {
appendArgWord(currentArg,word);
} else {
if (isCppKeyword(word)) {
appendArgWord(currentArg,word);
}
}
result += currentArg.trimmed();
return result;
}
bool CppParser::isNotFuncArgs(int startIndex, int endIndex) bool CppParser::isNotFuncArgs(int startIndex)
{ {
Q_ASSERT(mTokenizer[startIndex]->text=='(');
int endIndex=mTokenizer[startIndex]->matchIndex;
//no args, it must be a function //no args, it must be a function
if (endIndex-startIndex==1) if (endIndex-startIndex==1)
return false; return false;
@ -4709,25 +4825,37 @@ bool CppParser::isNotFuncArgs(int startIndex, int endIndex)
// args contains a string/char, can't be a func define // args contains a string/char, can't be a func define
case '"': case '"':
case '\'': case '\'':
return true; case '+':
case '(': case '-':
case '[': case '/':
case '|':
case '!':
case '{': case '{':
return true;
case '[': // function args like int f[10]
i=mTokenizer[i]->matchIndex+1; i=mTokenizer[i]->matchIndex+1;
if (i<endPos &&
(mTokenizer[i]->text=='('
|| mTokenizer[i]->text=='{')) //lambda
return true;
continue; continue;
} }
if (isDigitChar(ch)) if (isDigitChar(ch))
return true; return true;
if (isLetterChar(ch)) { if (isIdentChar(ch)) {
QString currentText=mTokenizer[i]->text; QString currentText=mTokenizer[i]->text;
while (currentText.startsWith('*') if (mTokenizer[i]->text.endsWith('.'))
|| currentText.startsWith('&')) return true;
currentText.remove(0,1); if (mTokenizer[i]->text.endsWith("->"))
return true;
if (!mCppTypeKeywords.contains(currentText)) { if (!mCppTypeKeywords.contains(currentText)) {
if (currentText=="true" || currentText=="false" || currentText=="nullptr" || if (currentText=="true" || currentText=="false" || currentText=="nullptr" ||
currentText=='this') currentText=='this')
return true; return true;
if (currentText=="const" ) if (currentText=="const")
return false;
if (isCppKeyword(currentText))
return false; return false;
PStatement statement =findStatementOf(mCurrentFile,word,getCurrentScope(),true); PStatement statement =findStatementOf(mCurrentFile,word,getCurrentScope(),true);
@ -4867,6 +4995,38 @@ int CppParser::indexPassBraces(int index)
return index; return index;
} }
void CppParser::skipNextSemicolon(int index)
{
mIndex=index;
while (mIndex<mTokenizer.tokenCount()) {
switch(mTokenizer[mIndex]->text[0].unicode()) {
case ';':
mIndex++;
return;
case '{':
mIndex = mTokenizer[mIndex]->matchIndex+1;
break;
case '(':
mIndex = mTokenizer[mIndex]->matchIndex+1;
break;
default:
mIndex++;
}
}
}
void CppParser::skipParenthesis(int index)
{
mIndex=index;
while (mIndex<mTokenizer.tokenCount()) {
if (mTokenizer[mIndex]->text=='(') {
mIndex=mTokenizer[mIndex]->matchIndex+1;
return;
}
mIndex++;
}
}
QString CppParser::mergeArgs(int startIndex, int endIndex) QString CppParser::mergeArgs(int startIndex, int endIndex)
{ {
QString result; QString result;

View File

@ -214,7 +214,7 @@ private:
int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results
bool checkForNamespace(KeywordType keywordType); bool checkForNamespace(KeywordType keywordType);
bool checkForPreprocessor(); bool checkForPreprocessor();
bool checkForLambda(); // bool checkForLambda();
bool checkForScope(KeywordType keywordType); bool checkForScope(KeywordType keywordType);
void checkForSkipStatement(); void checkForSkipStatement();
bool checkForStructs(KeywordType keywordType); bool checkForStructs(KeywordType keywordType);
@ -222,6 +222,8 @@ private:
bool checkForTypedefStruct(); bool checkForTypedefStruct();
bool checkForUsing(KeywordType keywordType); bool checkForUsing(KeywordType keywordType);
void checkAndHandleMethodOrVar();
void fillListOfFunctions(const QString& fileName, int line, void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement, const PStatement& statement,
const PStatement& scopeStatement, QStringList& list); const PStatement& scopeStatement, QStringList& list);
@ -321,7 +323,7 @@ private:
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);
bool isIdentifier(const QString& token) const { bool isIdentifier(const QString& token) const {
return (!token.isEmpty() && isLetterChar(token.front()) return (!token.isEmpty() && isIdentChar(token.front())
&& !token.contains('\"')); && !token.contains('\"'));
} }
@ -333,7 +335,7 @@ private:
case '\'': case '\'':
return false; return false;
default: default:
return isLetterChar(term[0]); return isIdentChar(term[0]);
} }
} }
@ -361,6 +363,16 @@ private:
return false; return false;
return (token.startsWith('\'')); return (token.startsWith('\''));
} }
bool isKeyword(const QString& token) const {
return mCppKeywords.contains(token);
}
bool tokenIsIdentifier(const QString& token) const {
//token won't be empty
return isIdentChar(token[0]);
}
PStatement doParseEvalTypeInfo( PStatement doParseEvalTypeInfo(
const QString& fileName, const QString& fileName,
const PStatement& scope, const PStatement& scope,
@ -402,10 +414,10 @@ private:
void handleKeyword(KeywordType skipType); void handleKeyword(KeywordType skipType);
void handleLambda(); void handleLambda();
void handleMethod( void handleMethod(
StatementKind functionKind,
const QString& sType, const QString& sType,
const QString& sName, const QString& sName,
int argStart, int argStart,
int argEnd,
bool isStatic, bool isStatic,
bool isFriend); bool isFriend);
void handleNamespace(KeywordType skipType); void handleNamespace(KeywordType skipType);
@ -415,7 +427,7 @@ private:
bool handleStatement(); bool handleStatement();
void handleStructs(bool isTypedef = false); void handleStructs(bool isTypedef = false);
void handleUsing(); void handleUsing();
bool tryHandleVar(); void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
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(
@ -443,8 +455,9 @@ private:
int argEnd); int argEnd);
QString splitPhrase(const QString& phrase, QString& sClazz, QString splitPhrase(const QString& phrase, QString& sClazz,
QString& sOperator, QString &sMember); QString& sOperator, QString &sMember);
QString removeTemplateParams(const QString& phrase);
QString removeArgNames(const QString& args); bool splitLastMember(const QString& token, QString& lastMember, QString& remaining);
bool isSpaceChar(const QChar& ch) const { bool isSpaceChar(const QChar& ch) const {
return ch==' ' || ch =='\t'; return ch==' ' || ch =='\t';
@ -457,7 +470,14 @@ private:
|| ch == '&'; || ch == '&';
} }
bool isLetterChar(const QChar& ch) const { bool isIdentifier(const QChar& ch) const {
return ch.isLetter()
|| ch == '_'
|| ch == '~'
;
}
bool isIdentChar(const QChar& ch) const {
return ch.isLetter() return ch.isLetter()
|| ch == '_'; || ch == '_';
} }
@ -499,10 +519,6 @@ private:
} }
} }
bool isLeftParenthesis(const QString& text) const {
return text=="(";
}
/*';', '{', '}'*/ /*';', '{', '}'*/
bool isblockChar(const QChar& ch) const { bool isblockChar(const QChar& ch) const {
switch(ch.unicode()){ switch(ch.unicode()){
@ -545,7 +561,7 @@ private:
return ch=='\n' || ch=='\r'; return ch=='\n' || ch=='\r';
} }
bool isNotFuncArgs(int startIndex, int endIndex); bool isNotFuncArgs(int startIndex);
/** /**
* @brief Test if a statement is a class/struct/union/namespace/function * @brief Test if a statement is a class/struct/union/namespace/function
@ -569,6 +585,8 @@ private:
int indexOfNextLeftBrace(int index); int indexOfNextLeftBrace(int index);
int indexPassParenthesis(int index); int indexPassParenthesis(int index);
int indexPassBraces(int index); int indexPassBraces(int index);
void skipNextSemicolon(int index);
void skipParenthesis(int index);
QString mergeArgs(int startIndex, int endIndex); QString mergeArgs(int startIndex, int endIndex);
void parseCommandTypeAndArgs(QString& command, void parseCommandTypeAndArgs(QString& command,
QString& typeSuffix, QString& typeSuffix,

View File

@ -112,6 +112,7 @@ void CppTokenizer::addToken(const QString &sText, int iLine, TokenType tokenType
PToken token = std::make_shared<Token>(); PToken token = std::make_shared<Token>();
token->text = sText; token->text = sText;
token->line = iLine; token->line = iLine;
token->matchIndex = 1000000000;
switch(tokenType) { switch(tokenType) {
case TokenType::LeftBrace: case TokenType::LeftBrace:
token->matchIndex=-1; token->matchIndex=-1;
@ -167,15 +168,6 @@ void CppTokenizer::countLines()
} }
} }
QString CppTokenizer::getLambdaCaptures()
{
QChar* offset = mCurrent;
skipPair('[', ']');
QString result(offset,mCurrent-offset);
skipToNextToken();
return result;
}
QString CppTokenizer::getForInit() QString CppTokenizer::getForInit()
{ {
QChar* startOffset = mCurrent; QChar* startOffset = mCurrent;
@ -290,33 +282,18 @@ QString CppTokenizer::getNextToken(TokenType *pTokenType, bool bSkipArray, bool
done = true; done = true;
break; break;
case '[': case '[':
{ if (*(mCurrent+1)!='[') {
// QChar* backup=mCurrent; *pTokenType=TokenType::LambdaCaptures;
// skipPair('[',']'); countLines();
// skipToNextToken(); QChar* backup=mCurrent;
// qDebug()<<*mCurrent; skipPair('[',']');
// if (*mCurrent!='(') { result = QString(backup,mCurrent-backup);
// mCurrent=backup; done = true;
// advance(); } else {
// } else { skipPair('[',']'); // attribute, skipit
// mCurrent=backup; advance();
// skipPair('[',']'); }
// *pTokenType=TokenType::LambdaCaptures;
// countLines();
// result = QString(backup,mCurrent-backup);
// done = true;
// qDebug()<<"yes"<<result;
// }
*pTokenType=TokenType::LambdaCaptures;
countLines();
QChar* backup=mCurrent;
skipPair('[',']');
result = QString(backup,mCurrent-backup);
done = true;
// qDebug()<<"yes"<<result;
break; break;
}
case ')': case ')':
*pTokenType=TokenType::RightParenthesis; *pTokenType=TokenType::RightParenthesis;
countLines(); countLines();
@ -430,10 +407,11 @@ QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
// Skip template contents, but keep template variable types // Skip template contents, but keep template variable types
if (*mCurrent == '<') { if (*mCurrent == '<') {
offset = mCurrent; //we don't skip offset = mCurrent;
skipTemplateArgs();
if (!bFoundTemplate) { if (bFoundTemplate) {
skipTemplateArgs();
} else if (skipAngleBracketPair()){
result += QString(offset, mCurrent-offset); result += QString(offset, mCurrent-offset);
skipToNextToken(); skipToNextToken();
} }
@ -630,6 +608,61 @@ void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QC
} }
} }
bool CppTokenizer::skipAngleBracketPair()
{
QChar* backup=mCurrent;
int level=0;
while (*mCurrent != '\0') {
switch((*mCurrent).unicode()) {
case '<':
case '(':
case '[':
level++;
break;
case ')':
case ']':
level--;
if (level==0) {
mCurrent=backup;
return false;
}
break;
case '>':
level--;
if (level==0) {
mCurrent++; //skip over >
return true;
}
break;
case '{':
case '}':
case ';':
case '"':
case '\'':
mCurrent=backup;
return false;
case '-':
if (*(mCurrent+1)=='>') {
mCurrent=backup;
return false;
}
break;
case '.':
if (*(mCurrent+1)!='.') {
mCurrent=backup;
return false;
}
// skip
while (*(mCurrent+1)=='.')
mCurrent++;
break;
}
mCurrent++;
}
mCurrent=backup;
return false;
}
void CppTokenizer::skipRawString() void CppTokenizer::skipRawString()
{ {
mCurrent++; //skip R mCurrent++; //skip R
@ -678,17 +711,8 @@ void CppTokenizer::skipTemplateArgs()
{ {
if (*mCurrent != '<') if (*mCurrent != '<')
return; return;
QChar* start = mCurrent;
QSet<QChar> failSet; skipPair('<', '>');
failSet.insert('{');
failSet.insert('}');
failSet.insert(';');
skipPair('<', '>', failSet);
// if we failed, return to where we came from
if (start!=mCurrent && *(mCurrent - 1) != '>')
mCurrent = start;
} }
void CppTokenizer::skipToEOL() void CppTokenizer::skipToEOL()

View File

@ -56,7 +56,6 @@ private:
void advance(); void advance();
void countLines(); void countLines();
PToken getToken(int index); PToken getToken(int index);
QString getLambdaCaptures();
QString getForInit(); QString getForInit();
QString getNextToken( QString getNextToken(
@ -79,6 +78,7 @@ private:
void skipAssignment(); void skipAssignment();
void skipDoubleQuotes(); void skipDoubleQuotes();
void skipPair(const QChar& cStart, const QChar cEnd, const QSet<QChar>& failChars = QSet<QChar>()); void skipPair(const QChar& cStart, const QChar cEnd, const QSet<QChar>& failChars = QSet<QChar>());
bool skipAngleBracketPair();
void skipRawString(); void skipRawString();
void skipSingleQuote(); void skipSingleQuote();
void skipSplitLine(); void skipSplitLine();

View File

@ -79,7 +79,6 @@ void initParser()
CppKeywords.insert("or_eq",KeywordType::SkipItself); CppKeywords.insert("or_eq",KeywordType::SkipItself);
CppKeywords.insert("register",KeywordType::SkipItself); CppKeywords.insert("register",KeywordType::SkipItself);
CppKeywords.insert("reinterpret_cast",KeywordType::SkipItself); CppKeywords.insert("reinterpret_cast",KeywordType::SkipItself);
CppKeywords.insert("static_assert",KeywordType::SkipItself);
CppKeywords.insert("static_cast",KeywordType::SkipItself); CppKeywords.insert("static_cast",KeywordType::SkipItself);
CppKeywords.insert("template",KeywordType::SkipItself); CppKeywords.insert("template",KeywordType::SkipItself);
//CppKeywords.insert("this",SkipType::skItself); //CppKeywords.insert("this",SkipType::skItself);
@ -97,32 +96,34 @@ void initParser()
CppKeywords.insert("try",KeywordType::SkipItself); CppKeywords.insert("try",KeywordType::SkipItself);
// Skip to ; // Skip to ;
CppKeywords.insert("delete",KeywordType::SkipAfterSemicolon); CppKeywords.insert("delete",KeywordType::SkipNextSemicolon);
CppKeywords.insert("delete[]",KeywordType::SkipAfterSemicolon); CppKeywords.insert("delete[]",KeywordType::SkipNextSemicolon);
CppKeywords.insert("goto",KeywordType::SkipAfterSemicolon); CppKeywords.insert("goto",KeywordType::SkipNextSemicolon);
CppKeywords.insert("new",KeywordType::SkipAfterSemicolon); CppKeywords.insert("new",KeywordType::SkipNextSemicolon);
CppKeywords.insert("return",KeywordType::SkipAfterSemicolon); CppKeywords.insert("return",KeywordType::SkipNextSemicolon);
CppKeywords.insert("throw",KeywordType::SkipAfterSemicolon); CppKeywords.insert("throw",KeywordType::SkipNextSemicolon);
// CppKeywords.insert("using",SkipType::skToSemicolon); //won't use it // CppKeywords.insert("using",SkipType::skToSemicolon); //won't use it
// Skip to : // Skip to :
CppKeywords.insert("case",KeywordType::SkipAfterColon); CppKeywords.insert("case",KeywordType::SkipNextColon);
CppKeywords.insert("default",KeywordType::SkipAfterColon); CppKeywords.insert("default",KeywordType::SkipNextColon);
// Skip to ) // Skip to )
CppKeywords.insert("__attribute__",KeywordType::SkipAfterParenthesis); CppKeywords.insert("__attribute__",KeywordType::SkipNextParenthesis);
CppKeywords.insert("alignas",KeywordType::SkipAfterParenthesis); // not right CppKeywords.insert("__attribute",KeywordType::SkipNextParenthesis);
CppKeywords.insert("alignof",KeywordType::SkipAfterParenthesis); // not right CppKeywords.insert("alignas",KeywordType::SkipNextParenthesis); // not right
CppKeywords.insert("decltype",KeywordType::SkipAfterParenthesis); // not right CppKeywords.insert("alignof",KeywordType::SkipNextParenthesis); // not right
CppKeywords.insert("if",KeywordType::SkipAfterParenthesis); CppKeywords.insert("decltype",KeywordType::SkipNextParenthesis); // not right
CppKeywords.insert("sizeof",KeywordType::SkipAfterParenthesis); CppKeywords.insert("if",KeywordType::SkipNextParenthesis);
CppKeywords.insert("switch",KeywordType::SkipAfterParenthesis); CppKeywords.insert("sizeof",KeywordType::SkipNextParenthesis);
CppKeywords.insert("typeid",KeywordType::SkipAfterParenthesis); CppKeywords.insert("switch",KeywordType::SkipNextParenthesis);
CppKeywords.insert("while",KeywordType::SkipAfterParenthesis); CppKeywords.insert("typeid",KeywordType::SkipNextParenthesis);
CppKeywords.insert("while",KeywordType::SkipNextParenthesis);
CppKeywords.insert("static_assert",KeywordType::SkipNextParenthesis);
// Skip to } // Skip to }
CppKeywords.insert("asm",KeywordType::SkipAfterBrace); CppKeywords.insert("asm",KeywordType::MoveToRightBrace);
//CppKeywords.insert("namespace",SkipType::skToLeftBrace); // won't process it CppKeywords.insert("__asm",KeywordType::MoveToRightBrace);
// Skip to { // Skip to {
// wont handle // wont handle

View File

@ -58,11 +58,11 @@ using PDefineMap = std::shared_ptr<DefineMap>;
enum class KeywordType { enum class KeywordType {
SkipItself, // skip itself SkipItself, // skip itself
SkipAfterSemicolon, // skip to ; SkipNextSemicolon, // move to ; and skip it
SkipAfterColon, // skip to : SkipNextColon, // move to : and skip it
SkipAfterParenthesis, // skip to ) SkipNextParenthesis, // move to ) and skip it
SkipToLeftBrace,// Skip to { MoveToLeftBrace,// move to {
SkipAfterBrace, // skip to } MoveToRightBrace, // move to }
For, //for For, //for
Catch, //catch Catch, //catch
Public, // public Public, // public
@ -74,7 +74,8 @@ enum class KeywordType {
Namespace, //namespace Namespace, //namespace
Typedef, //typedef Typedef, //typedef
Using, //using Using, //using
None // It's a keyword but don't process here None, // It's a keyword but don't process here
NotKeyword
}; };
//It will be used as hash key. DONT make it enum class!!!!! //It will be used as hash key. DONT make it enum class!!!!!