From 8db5c531ab7685ab4cd61e214a32946cfc75d8ea Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 7 Dec 2021 08:23:27 +0800 Subject: [PATCH] work save --- RedPandaIDE/parser/cppparser.cpp | 135 ++++++++++++++++++++++++----- RedPandaIDE/parser/cppparser.h | 23 +++-- RedPandaIDE/parser/parserutils.cpp | 16 +++- RedPandaIDE/parser/parserutils.h | 13 ++- 4 files changed, 156 insertions(+), 31 deletions(-) diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 347d79ec..a0b04dd7 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -1,6 +1,7 @@ #include "cppparser.h" #include "parserutils.h" #include "../utils.h" +#include "../qsynedit/highlighter/cpp.h" #include #include @@ -302,20 +303,7 @@ PStatement CppParser::findStatementOf(const QString &fileName, //unqualified name parentScopeType = currentScope; remainder = splitPhrase(remainder,nextScopeWord,operatorToken,memberName); - if (currentScope && (currentScope->kind == StatementKind::skNamespace)) { - PStatementList namespaceList = mNamespaces.value(currentScope->fullName); - if (!namespaceList || namespaceList->isEmpty()) - return PStatement(); - for (PStatement& currentNamespace:*namespaceList){ - statement = findMemberOfStatement(nextScopeWord,currentNamespace); - if (statement) - break; - } - if (!statement) - statement = findStatementStartingFrom(fileName,nextScopeWord,currentScope->parentScope.lock(),force); - } else { - statement = findStatementStartingFrom(fileName,nextScopeWord,parentScopeType,force); - } + statement = findStatementStartingFrom(fileName,nextScopeWord,parentScopeType); if (!statement) return PStatement(); } @@ -430,12 +418,8 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph return findStatementOf(fileName,phrase,currentClass,statementParentType,force); } -PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope, bool force) +PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope) { - QMutexLocker locker(&mMutex); - if (mParsing && !force) - return PStatement(); - PStatement scopeStatement = startScope; // repeat until reach global @@ -1762,7 +1746,9 @@ PStatement CppParser::getTypeDef(const PStatement& statement, if (!statement) { return PStatement(); } - if (statement->kind == StatementKind::skClass) { + if (statement->kind == StatementKind::skClass + || statement->kind == StatementKind::skEnumType + || statement->kind == StatementKind::skEnumClassType) { return statement; } else if (statement->kind == StatementKind::skTypedef) { if (statement->type == aType) // prevent infinite loop @@ -3553,7 +3539,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, newResult->assignType(result); pos++; // skip ")" result = newResult; - } else if (result->kind == StatementKind::Function) { + } else if (result->kind == EvalStatementKind::Function) { doSkipInExpression("(",")"); //function call result->kind = EvalStatementKind::Variable; @@ -3638,7 +3624,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName, return result; if (phraseExpression[pos]=="(") { pos++; - PStatement statement = doEvalExpression(fileName,phraseExpression,pos,currentScope,freeScoped); + result = doEvalExpression(fileName,phraseExpression,pos,scope,PEvalStatement(),freeScoped); if (pos >= phraseExpression.length() || phraseExpression[pos]!=")") return PEvalStatement(); else { @@ -3646,7 +3632,17 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName, return result; } } else if (isIdentifier(phraseExpression[pos])) { - + PStatement statement; + if (!freeScoped && !previousResult) { + statement = findMemberOfStatement(phraseExpression[pos],PStatement()); + pos++; + } else if (freeScoped && !previousResult) { + statement = findStatementStartingFrom( + fileName, + phraseExpression[pos], + scope, + true); + } } else if (isIntegerLiteral(phraseExpression[pos])) { } else if (isIntegerLiteral(phraseExpression[pos])) { } else if (isFloatLiteral(phraseExpression[pos])) { @@ -3657,6 +3653,99 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName, } +PEvalStatement CppParser::doCreateEvalType(const PStatement &typeStatement) +{ + Q_ASSERT(typeStatement); + Q_ASSERT(typeStatement->kind == StatementKind::skClass + || typeStatement->kind == StatementKind::skEnumType + || typeStatement->kind == StatementKind::skEnumClassType); + return EvalStatement::create( + typeStatement->fullName, + EvalStatementKind::Type, + typeStatement, + typeStatement); +} + +PEvalStatement CppParser::doCreateEvalVariable(const QString &fileName, PStatement varStatement, const PStatement &scope) +{ + Q_ASSERT(varStatement); + Q_ASSERT(varStatement->kind == StatementKind::skVariable); + QString baseType; + int pointerLevel=0; + PStatement typeStatement = doParseEvalTypeInfo( + fileName, + varStatement->parentScope.lock(), + varStatement->type, + baseType, + pointerLevel); + return EvalStatement::create( + baseType, + EvalStatementKind::Variable, + varStatement, + typeStatement, + pointerLevel + ); +} + +PStatement CppParser::doParseEvalTypeInfo( + const QString &fileName, + const PStatement &scope, + const QString &type, + QString &baseType, + int &pointerLevel) +{ + // Remove pointer stuff from type + QString s = type; // 'Type' is a keyword + int position = s.length()-1; + SynEditCppHighlighter highlighter; + highlighter.resetState(); + highlighter.setLine(type,0); + int bracketLevel = 0; + int templateLevel = 0; + while(!highlighter.eol()) { + QString token = highlighter.getToken(); + if (bracketLevel == 0 && templateLevel ==0) { + if (token == "*") + pointerLevel++; + else if (token == "&") + pointerLevel--; + else if (highlighter.getTokenAttribute() == highlighter.identifierAttribute()) { + if (token!= "const") + baseType = token; + } else if (token == "[") { + bracketLevel++; + } else if (token == "<") { + templateLevel++; + } + } else if (bracketLevel > 0) { + if (token == "[") { + bracketLevel++; + } else if (token == "]") { + bracketLevel++; + } + } else if (templateLevel > 0) { + if (token == "<") { + templateLevel++; + } else if (token == ">") { + templateLevel++; + } + } + highlighter.next(); + } + while ((position >= 0) && (s[position] == '*' + || s[position] == ' ' + || s[position] == '&')) { + if (s[position]=='*') { + + } + position--; + } + + PStatement statement = findStatementOf(fileName,s,scope); + return getTypeDef(statement,fileName,type); + +} + int CppParser::getBracketEnd(const QString &s, int startAt) { int i = startAt; diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 3d681f28..cf5115fa 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -59,11 +59,6 @@ public: PEvalStatement evalExpression(const QString& fileName, const QStringList& expression, const PStatement& currentScope); - //{Find statement starting from startScope} - PStatement findStatementStartingFrom(const QString& fileName, - const QString& phrase, - const PStatement& startScope, - bool force = false); PStatement findTypeDefinitionOf(const QString& fileName, const QString& aType, const PStatement& currentClass); @@ -209,6 +204,12 @@ private: const QString& name, const QString& namespaceName); + //{Find statement starting from startScope} + PStatement findStatementStartingFrom(const QString& fileName, + const QString& phrase, + const PStatement& startScope); + + /** * @brief evaluate the expression (starting from pos) in the scope * @param fileName @@ -262,6 +263,18 @@ private: const PEvalStatement& previousResult, bool freeScoped); + + PEvalStatement doCreateEvalType(const PStatement& typeStatement); + + PEvalStatement doCreateEvalVariable(const QString& fileName, PStatement varStatement, const PStatement& scope); + + PStatement doParseEvalTypeInfo( + const QString& fileName, + const PStatement& scope, + const QString& type, + QString& baseType, + int& pointerLevel); + int getBracketEnd(const QString& s, int startAt); StatementClassScope getClassScope(int index); int getCurrentBlockBeginSkip(); diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 1d363b9e..93895dea 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -499,12 +499,26 @@ bool isScopeTypeKind(StatementKind kind) } } -PEvalStatement EvalStatement::create(const QString &baseType, EvalStatementKind kind, const PStatement &baseStatement, int pointerLevel) +PEvalStatement EvalStatement::create( + const QString &baseType, + EvalStatementKind kind, + const PStatement &baseStatement, + const PStatement &effetiveTypeStatement, + int pointerLevel) { PEvalStatement result = std::make_shared(); result->baseType = baseType; result->kind = kind; result->baseStatement = baseStatement; + result->effectiveTypeStatement = effectiveTypeStatement; result->pointerLevel = pointerLevel; return result; } + +void EvalStatement::assignType(const PEvalStatement &typeStatement) +{ + Q_ASSERT(typeStatement && typeStatement->kind==EvalStatementKind::Type); + baseType = typeStatement->baseType; + pointerLevel = typeStatement->pointerLevel; + effectiveTypeStatement = typeStatement->baseStatement; +} diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index eedcc764..9e9324e5 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -148,17 +148,26 @@ struct Statement { struct EvalStatement; using PEvalStatement = std::shared_ptr; -// Statement for evaluation result +/** + * @brief Statement for evaluation result + * Ex. (Test*)(y+1) + * it's baseStatement is the statement for y + * it's effetiveTypeStatement is Test + */ struct EvalStatement { QString baseType; // type "int" EvalStatementKind kind; // namespace / type / variable / function / literal int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"... PStatement baseStatement; // if not literal or primitive type, the base statement + PStatement effectiveTypeStatement; public: - PEvalStatement create(const QString& baseType, + static PEvalStatement create(const QString& baseType, EvalStatementKind kind, const PStatement& baseStatement, + const PStatement& typeStatement, int pointerLevel = 0); + void assignType(const PEvalStatement& typeStatement); + };