work save

This commit is contained in:
Roy Qu 2021-12-07 08:23:27 +08:00
parent d554e6dba5
commit 8db5c531ab
4 changed files with 156 additions and 31 deletions

View File

@ -1,6 +1,7 @@
#include "cppparser.h"
#include "parserutils.h"
#include "../utils.h"
#include "../qsynedit/highlighter/cpp.h"
#include <QApplication>
#include <QDate>
@ -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;

View File

@ -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();

View File

@ -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<EvalStatement>();
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;
}

View File

@ -148,17 +148,26 @@ struct Statement {
struct EvalStatement;
using PEvalStatement = std::shared_ptr<EvalStatement>;
// 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);
};