- improve template parameters checker
- streamline cppparser
This commit is contained in:
parent
ef79640eb0
commit
8d9740dd57
4
NEWS.md
4
NEWS.md
|
@ -1,8 +1,8 @@
|
|||
Red Panda C++ Version 2.2
|
||||
|
||||
- enhancement: basic code completion support for C++ lambda
|
||||
- enhancement: basic code completion support for C++ lambdas
|
||||
- enhancement: slightly reduce parsing time
|
||||
- fix: Wrong charset name returned when saveing file
|
||||
- fix: Wrong charset name returned when saving file
|
||||
- fix: 'using =' / 'namespace =' not correctly handled
|
||||
- fix: Pressing '*' at begin of line will crash app
|
||||
|
||||
|
|
|
@ -957,7 +957,6 @@ void CppParser::resetParser()
|
|||
|
||||
mCurrentScope.clear();
|
||||
mCurrentClassScope.clear();
|
||||
mSkipList.clear();
|
||||
mStatementList.clear();
|
||||
|
||||
mProjectFiles.clear();
|
||||
|
@ -1460,7 +1459,8 @@ void CppParser::removeScopeLevel(int line)
|
|||
// qDebug()<<"--remove scope"<<mCurrentFile<<line<<mCurrentClassScope.count();
|
||||
PStatement currentScope = getCurrentScope();
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
|
||||
if (currentScope && (currentScope->kind == StatementKind::skBlock)) {
|
||||
if (currentScope) {
|
||||
if (currentScope->kind == StatementKind::skBlock) {
|
||||
if (currentScope->children.isEmpty()) {
|
||||
// remove no children block
|
||||
if (fileIncludes) {
|
||||
|
@ -1470,6 +1470,9 @@ void CppParser::removeScopeLevel(int line)
|
|||
} else {
|
||||
fileIncludes->statements.insert(currentScope->fullName,currentScope);
|
||||
}
|
||||
} else if (currentScope->kind == StatementKind::skClass) {
|
||||
mIndex=indexOfNextSemicolon(mIndex);
|
||||
}
|
||||
}
|
||||
mCurrentScope.pop_back();
|
||||
mCurrentClassScope.pop_back();
|
||||
|
@ -1494,7 +1497,6 @@ void CppParser::internalClear()
|
|||
mCurrentClassScope.clear();
|
||||
mIndex = 0;
|
||||
mClassScope = StatementClassScope::None;
|
||||
mSkipList.clear();
|
||||
mBlockBeginSkips.clear();
|
||||
mBlockEndSkips.clear();
|
||||
mInlineNamespaceEndSkips.clear();
|
||||
|
@ -1729,14 +1731,6 @@ bool CppParser::checkForScope(KeywordType keywordType)
|
|||
);
|
||||
}
|
||||
|
||||
void CppParser::checkForSkipStatement()
|
||||
{
|
||||
if ((mSkipList.count()>0) && (mIndex == mSkipList.back())) { // skip to next ';'
|
||||
skipNextSemicolon(mIndex);
|
||||
mSkipList.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
bool CppParser::checkForStructs(KeywordType keywordType)
|
||||
{
|
||||
int dis = 0;
|
||||
|
@ -2181,7 +2175,7 @@ void CppParser::handleCatchBlock()
|
|||
true,
|
||||
false);
|
||||
addSoloScopeLevel(block,startLine);
|
||||
scanMethodArgs(block,mIndex, mTokenizer[mIndex]->matchIndex);
|
||||
scanMethodArgs(block,mIndex);
|
||||
mIndex=mTokenizer[mIndex]->matchIndex+1;
|
||||
}
|
||||
|
||||
|
@ -2450,8 +2444,9 @@ void CppParser::handleKeyword(KeywordType skipType)
|
|||
void CppParser::handleLambda(int index)
|
||||
{
|
||||
Q_ASSERT(mTokenizer[index]->text.startsWith('['));
|
||||
Q_ASSERT(mTokenizer[index+1]->text.startsWith('('));
|
||||
int startLine=mTokenizer[index]->line;
|
||||
int argStart=index;
|
||||
int argStart=index+1;
|
||||
int argEnd= mTokenizer[argStart]->matchIndex;
|
||||
int blockLine=mTokenizer[argStart]->line;
|
||||
//TODO: parse captures
|
||||
|
@ -2473,7 +2468,7 @@ void CppParser::handleLambda(int index)
|
|||
StatementClassScope::None,
|
||||
true,
|
||||
false);
|
||||
scanMethodArgs(lambdaBlock,argStart,argEnd);
|
||||
scanMethodArgs(lambdaBlock,argStart);
|
||||
addSoloScopeLevel(lambdaBlock,blockLine);
|
||||
}
|
||||
|
||||
|
@ -2536,7 +2531,6 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
|
|||
scopeStatement->friends.insert(scopelessName);
|
||||
} else if (isValid) {
|
||||
// Use the class the function belongs to as the parent ID if the function is declared outside of the class body
|
||||
int delimPos = sName.lastIndexOf("::");
|
||||
QString scopelessName;
|
||||
QString parentClassName;
|
||||
if (splitLastMember(sName,scopelessName,parentClassName)) {
|
||||
|
@ -2563,7 +2557,7 @@ void CppParser::handleMethod(StatementKind functionKind,const QString &sType, co
|
|||
mClassScope,
|
||||
true,
|
||||
isStatic);
|
||||
scanMethodArgs(functionStatement, argStart,argEnd);
|
||||
scanMethodArgs(functionStatement, argStart);
|
||||
// add variable this to the class function
|
||||
if (scopeStatement && scopeStatement->kind == StatementKind::skClass &&
|
||||
!isStatic) {
|
||||
|
@ -3031,10 +3025,10 @@ bool CppParser::handleStatement()
|
|||
}
|
||||
Q_ASSERT(mIndex<999999);
|
||||
|
||||
while (mTokenizer.lambdasCount()>0 && mTokenizer.indexOfFirstLambda()<mIndex) {
|
||||
handleLambda(mTokenizer.indexOfFirstLambda());
|
||||
mTokenizer.removeFirstLambda();
|
||||
}
|
||||
// while (mTokenizer.lambdasCount()>0 && mTokenizer.indexOfFirstLambda()<mIndex) {
|
||||
// handleLambda(mTokenizer.indexOfFirstLambda());
|
||||
// mTokenizer.removeFirstLambda();
|
||||
// }
|
||||
// else if (checkForMethod(funcType, funcName, argStart,argEnd, isStatic, isFriend)) {
|
||||
// handleMethod(funcType, funcName, argStart, argEnd, isStatic, isFriend); // don't recalculate parts
|
||||
// } else if (tryHandleVar()) {
|
||||
|
@ -3043,7 +3037,7 @@ bool CppParser::handleStatement()
|
|||
// mIndex++;
|
||||
|
||||
//todo: remove mSkipList (we can check '}''s statement type instead)
|
||||
checkForSkipStatement();
|
||||
// checkForSkipStatement();
|
||||
|
||||
return mIndex < mTokenizer.tokenCount();
|
||||
|
||||
|
@ -3210,7 +3204,6 @@ void CppParser::handleStructs(bool isTypedef)
|
|||
mTokenizer[i + 1]->text.front() == ';'
|
||||
|| mTokenizer[i + 1]->text.front() == '}')) {
|
||||
// When encountering names again after struct body scanning, skip it
|
||||
mSkipList.append(i+1); // add first name to skip statement so that we can skip it until the next ;
|
||||
QString command = "";
|
||||
QString args = "";
|
||||
|
||||
|
@ -3599,7 +3592,7 @@ void CppParser::internalParse(const QString &fileName)
|
|||
|
||||
QStringList preprocessResult = mPreprocessor.result();
|
||||
#ifdef QT_DEBUG
|
||||
stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
|
||||
// stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
|
||||
// mPreprocessor.dumpDefinesTo("r:\\defines.txt");
|
||||
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
|
||||
#endif
|
||||
|
@ -3613,7 +3606,7 @@ void CppParser::internalParse(const QString &fileName)
|
|||
if (mTokenizer.tokenCount() == 0)
|
||||
return;
|
||||
#ifdef QT_DEBUG
|
||||
mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
|
||||
// mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
|
||||
#endif
|
||||
// Process the token list
|
||||
while(true) {
|
||||
|
@ -3621,8 +3614,8 @@ void CppParser::internalParse(const QString &fileName)
|
|||
break;
|
||||
}
|
||||
#ifdef QT_DEBUG
|
||||
mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
|
||||
mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
|
||||
// mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
|
||||
// mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
|
||||
#endif
|
||||
//reduce memory usage
|
||||
internalClear();
|
||||
|
@ -4637,8 +4630,10 @@ int CppParser::calcKeyLenForStruct(const QString &word)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart, int argEnd)
|
||||
void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart)
|
||||
{
|
||||
Q_ASSERT(mTokenizer[argStart]->text=='(');
|
||||
int argEnd=mTokenizer[argStart]->matchIndex;
|
||||
int paramStart = argStart+1;
|
||||
int i = paramStart ; // assume it starts with ( and ends with )
|
||||
// Keep going and stop on top of the variable name
|
||||
|
|
|
@ -216,7 +216,6 @@ private:
|
|||
bool checkForPreprocessor();
|
||||
// bool checkForLambda();
|
||||
bool checkForScope(KeywordType keywordType);
|
||||
void checkForSkipStatement();
|
||||
bool checkForStructs(KeywordType keywordType);
|
||||
bool checkForTypedefEnum();
|
||||
bool checkForTypedefStruct();
|
||||
|
@ -451,8 +450,7 @@ private:
|
|||
// }
|
||||
void scanMethodArgs(
|
||||
const PStatement& functionStatement,
|
||||
int argStart,
|
||||
int argEnd);
|
||||
int argStart);
|
||||
QString splitPhrase(const QString& phrase, QString& sClazz,
|
||||
QString& sOperator, QString &sMember);
|
||||
QString removeTemplateParams(const QString& phrase);
|
||||
|
@ -608,9 +606,6 @@ private:
|
|||
QVector<PStatement> mCurrentScope;
|
||||
QVector<StatementClassScope> mCurrentClassScope;
|
||||
|
||||
// the start index in tokens to skip to ; when parsing typedef struct we need to skip
|
||||
// the names after the closing bracket because we have processed it
|
||||
QVector<int> mSkipList; // TList<Integer>
|
||||
StatementClassScope mClassScope;
|
||||
StatementModel mStatementList;
|
||||
//It's used in preprocessor, so we can't use fIncludeList instead
|
||||
|
|
|
@ -113,7 +113,9 @@ void CppTokenizer::addToken(const QString &sText, int iLine, TokenType tokenType
|
|||
PToken token = std::make_shared<Token>();
|
||||
token->text = sText;
|
||||
token->line = iLine;
|
||||
#ifdef Q_DEBUG
|
||||
token->matchIndex = 1000000000;
|
||||
#endif
|
||||
switch(tokenType) {
|
||||
case TokenType::LeftBrace:
|
||||
token->matchIndex=-1;
|
||||
|
@ -573,16 +575,16 @@ void CppTokenizer::skipDoubleQuotes()
|
|||
}
|
||||
}
|
||||
|
||||
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, bool keepLambda)
|
||||
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd)
|
||||
{
|
||||
mCurrent++;
|
||||
while (*mCurrent != 0) {
|
||||
if (*mCurrent == '(') {
|
||||
skipPair('(', ')',keepLambda);
|
||||
skipPair('(', ')');
|
||||
} else if (*mCurrent == '[') {
|
||||
skipPair('[', ']',keepLambda);
|
||||
skipPair('[', ']');
|
||||
} else if (*mCurrent == '{') {
|
||||
skipPair('{', '}',keepLambda);
|
||||
skipPair('{', '}');
|
||||
} else if (*mCurrent == cStart) {
|
||||
skipPair(cStart, cEnd);
|
||||
} else if (*mCurrent == cEnd) {
|
||||
|
@ -603,8 +605,6 @@ void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, bool keepLamb
|
|||
skipSingleQuote(); // don't do it inside AnsiString!
|
||||
else
|
||||
mCurrent++;
|
||||
} else if (failChars.contains(*mCurrent)) {
|
||||
break;
|
||||
} else {
|
||||
mCurrent++;
|
||||
}
|
||||
|
@ -614,26 +614,40 @@ void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, bool keepLamb
|
|||
bool CppTokenizer::skipAngleBracketPair()
|
||||
{
|
||||
QChar* backup=mCurrent;
|
||||
int level=0;
|
||||
QVector<QChar> stack;
|
||||
while (*mCurrent != '\0') {
|
||||
switch((*mCurrent).unicode()) {
|
||||
case '<':
|
||||
case '(':
|
||||
case '[':
|
||||
level++;
|
||||
stack.push_back(*mCurrent);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
level--;
|
||||
if (level==0) {
|
||||
while (!stack.isEmpty() && stack.back()!='(') {
|
||||
stack.pop_back();
|
||||
}
|
||||
//pop up '('
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
stack.pop_back();
|
||||
break;
|
||||
case ']':
|
||||
while (!stack.isEmpty() && stack.back()!='[')
|
||||
stack.pop_back();
|
||||
//pop up '['
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
stack.pop_back();
|
||||
break;
|
||||
case '>':
|
||||
level--;
|
||||
if (level==0) {
|
||||
mCurrent++; //skip over >
|
||||
if (stack.back()=='<')
|
||||
stack.pop_back();
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent++;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
@ -766,9 +780,11 @@ void CppTokenizer::removeFirstLambda()
|
|||
void CppTokenizer::advance()
|
||||
{
|
||||
switch(mCurrent->unicode()) {
|
||||
case '\"': skipDoubleQuotes();
|
||||
case '\"':
|
||||
skipDoubleQuotes();
|
||||
break;
|
||||
case '\'': skipSingleQuote();
|
||||
case '\'':
|
||||
skipSingleQuote();
|
||||
break;
|
||||
case '/':
|
||||
if (*(mCurrent + 1) == '=')
|
||||
|
|
Loading…
Reference in New Issue