work save
This commit is contained in:
parent
20917e3a8b
commit
585d7678d4
1
NEWS.md
1
NEWS.md
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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!!!!!
|
||||||
|
|
Loading…
Reference in New Issue