work save
This commit is contained in:
parent
d554e6dba5
commit
8db5c531ab
|
@ -1,6 +1,7 @@
|
||||||
#include "cppparser.h"
|
#include "cppparser.h"
|
||||||
#include "parserutils.h"
|
#include "parserutils.h"
|
||||||
#include "../utils.h"
|
#include "../utils.h"
|
||||||
|
#include "../qsynedit/highlighter/cpp.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
|
@ -302,20 +303,7 @@ PStatement CppParser::findStatementOf(const QString &fileName,
|
||||||
//unqualified name
|
//unqualified name
|
||||||
parentScopeType = currentScope;
|
parentScopeType = currentScope;
|
||||||
remainder = splitPhrase(remainder,nextScopeWord,operatorToken,memberName);
|
remainder = splitPhrase(remainder,nextScopeWord,operatorToken,memberName);
|
||||||
if (currentScope && (currentScope->kind == StatementKind::skNamespace)) {
|
statement = findStatementStartingFrom(fileName,nextScopeWord,parentScopeType);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (!statement)
|
if (!statement)
|
||||||
return PStatement();
|
return PStatement();
|
||||||
}
|
}
|
||||||
|
@ -430,12 +418,8 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
|
||||||
return findStatementOf(fileName,phrase,currentClass,statementParentType,force);
|
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;
|
PStatement scopeStatement = startScope;
|
||||||
|
|
||||||
// repeat until reach global
|
// repeat until reach global
|
||||||
|
@ -1762,7 +1746,9 @@ PStatement CppParser::getTypeDef(const PStatement& statement,
|
||||||
if (!statement) {
|
if (!statement) {
|
||||||
return PStatement();
|
return PStatement();
|
||||||
}
|
}
|
||||||
if (statement->kind == StatementKind::skClass) {
|
if (statement->kind == StatementKind::skClass
|
||||||
|
|| statement->kind == StatementKind::skEnumType
|
||||||
|
|| statement->kind == StatementKind::skEnumClassType) {
|
||||||
return statement;
|
return statement;
|
||||||
} else if (statement->kind == StatementKind::skTypedef) {
|
} else if (statement->kind == StatementKind::skTypedef) {
|
||||||
if (statement->type == aType) // prevent infinite loop
|
if (statement->type == aType) // prevent infinite loop
|
||||||
|
@ -3553,7 +3539,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
|
||||||
newResult->assignType(result);
|
newResult->assignType(result);
|
||||||
pos++; // skip ")"
|
pos++; // skip ")"
|
||||||
result = newResult;
|
result = newResult;
|
||||||
} else if (result->kind == StatementKind::Function) {
|
} else if (result->kind == EvalStatementKind::Function) {
|
||||||
doSkipInExpression("(",")");
|
doSkipInExpression("(",")");
|
||||||
//function call
|
//function call
|
||||||
result->kind = EvalStatementKind::Variable;
|
result->kind = EvalStatementKind::Variable;
|
||||||
|
@ -3638,7 +3624,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
return result;
|
return result;
|
||||||
if (phraseExpression[pos]=="(") {
|
if (phraseExpression[pos]=="(") {
|
||||||
pos++;
|
pos++;
|
||||||
PStatement statement = doEvalExpression(fileName,phraseExpression,pos,currentScope,freeScoped);
|
result = doEvalExpression(fileName,phraseExpression,pos,scope,PEvalStatement(),freeScoped);
|
||||||
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")")
|
if (pos >= phraseExpression.length() || phraseExpression[pos]!=")")
|
||||||
return PEvalStatement();
|
return PEvalStatement();
|
||||||
else {
|
else {
|
||||||
|
@ -3646,7 +3632,17 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else if (isIdentifier(phraseExpression[pos])) {
|
} 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 (isIntegerLiteral(phraseExpression[pos])) {
|
} else if (isIntegerLiteral(phraseExpression[pos])) {
|
||||||
} else if (isFloatLiteral(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 CppParser::getBracketEnd(const QString &s, int startAt)
|
||||||
{
|
{
|
||||||
int i = startAt;
|
int i = startAt;
|
||||||
|
|
|
@ -59,11 +59,6 @@ public:
|
||||||
PEvalStatement evalExpression(const QString& fileName,
|
PEvalStatement evalExpression(const QString& fileName,
|
||||||
const QStringList& expression,
|
const QStringList& expression,
|
||||||
const PStatement& currentScope);
|
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,
|
PStatement findTypeDefinitionOf(const QString& fileName,
|
||||||
const QString& aType,
|
const QString& aType,
|
||||||
const PStatement& currentClass);
|
const PStatement& currentClass);
|
||||||
|
@ -209,6 +204,12 @@ private:
|
||||||
const QString& name,
|
const QString& name,
|
||||||
const QString& namespaceName);
|
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
|
* @brief evaluate the expression (starting from pos) in the scope
|
||||||
* @param fileName
|
* @param fileName
|
||||||
|
@ -262,6 +263,18 @@ private:
|
||||||
const PEvalStatement& previousResult,
|
const PEvalStatement& previousResult,
|
||||||
bool freeScoped);
|
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);
|
int getBracketEnd(const QString& s, int startAt);
|
||||||
StatementClassScope getClassScope(int index);
|
StatementClassScope getClassScope(int index);
|
||||||
int getCurrentBlockBeginSkip();
|
int getCurrentBlockBeginSkip();
|
||||||
|
|
|
@ -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>();
|
PEvalStatement result = std::make_shared<EvalStatement>();
|
||||||
result->baseType = baseType;
|
result->baseType = baseType;
|
||||||
result->kind = kind;
|
result->kind = kind;
|
||||||
result->baseStatement = baseStatement;
|
result->baseStatement = baseStatement;
|
||||||
|
result->effectiveTypeStatement = effectiveTypeStatement;
|
||||||
result->pointerLevel = pointerLevel;
|
result->pointerLevel = pointerLevel;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EvalStatement::assignType(const PEvalStatement &typeStatement)
|
||||||
|
{
|
||||||
|
Q_ASSERT(typeStatement && typeStatement->kind==EvalStatementKind::Type);
|
||||||
|
baseType = typeStatement->baseType;
|
||||||
|
pointerLevel = typeStatement->pointerLevel;
|
||||||
|
effectiveTypeStatement = typeStatement->baseStatement;
|
||||||
|
}
|
||||||
|
|
|
@ -148,17 +148,26 @@ struct Statement {
|
||||||
|
|
||||||
struct EvalStatement;
|
struct EvalStatement;
|
||||||
using PEvalStatement = std::shared_ptr<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 {
|
struct EvalStatement {
|
||||||
QString baseType; // type "int"
|
QString baseType; // type "int"
|
||||||
EvalStatementKind kind; // namespace / type / variable / function / literal
|
EvalStatementKind kind; // namespace / type / variable / function / literal
|
||||||
int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"...
|
int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"...
|
||||||
PStatement baseStatement; // if not literal or primitive type, the base statement
|
PStatement baseStatement; // if not literal or primitive type, the base statement
|
||||||
|
PStatement effectiveTypeStatement;
|
||||||
public:
|
public:
|
||||||
PEvalStatement create(const QString& baseType,
|
static PEvalStatement create(const QString& baseType,
|
||||||
EvalStatementKind kind,
|
EvalStatementKind kind,
|
||||||
const PStatement& baseStatement,
|
const PStatement& baseStatement,
|
||||||
|
const PStatement& typeStatement,
|
||||||
int pointerLevel = 0);
|
int pointerLevel = 0);
|
||||||
|
void assignType(const PEvalStatement& typeStatement);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue