add a function to find statement by expression in the parser
This commit is contained in:
parent
cd5b281c90
commit
41336cf31f
|
@ -24,13 +24,12 @@ bool CppRefacter::findOccurence(Editor *editor, const BufferCoord &pos)
|
|||
editor->parser()->unFreeze();
|
||||
});
|
||||
// get full phrase (such as s.name instead of name)
|
||||
BufferCoord pBeginPos,pEndPos;
|
||||
QString phrase = getWordAtPosition(editor,pos,pBeginPos,pEndPos,Editor::WordPurpose::wpInformation);
|
||||
QStringList expression = editor->getExpressionAtPosition(pos);
|
||||
// Find it's definition
|
||||
PStatement statement = editor->parser()->findStatementOf(
|
||||
editor->filename(),
|
||||
phrase,
|
||||
pos.Line);
|
||||
expression,
|
||||
editor->parser()->findAndScanBlockAt(editor->filename(),pos.Line));
|
||||
// definition of the symbol not found
|
||||
if (!statement)
|
||||
return false;
|
||||
|
|
|
@ -1631,51 +1631,7 @@ QStringList Editor::getOwnerExpressionAndMemberAtPositionForCompletion(
|
|||
QStringList &memberExpression)
|
||||
{
|
||||
QStringList expression = getExpressionAtPosition(pos);
|
||||
//find position of the last member operator
|
||||
int lastMemberOperatorPos = -1;
|
||||
int currentMatchingLevel = 0;
|
||||
QString matchingSignLeft;
|
||||
QString matchingSignRight;
|
||||
for (int i=0;i<expression.length();i++) {
|
||||
QString token = expression[i];
|
||||
if (currentMatchingLevel == 0) {
|
||||
if (mParser->isMemberOperator(token)) {
|
||||
lastMemberOperatorPos = i;
|
||||
} else if (token == "(") {
|
||||
matchingSignLeft = "(";
|
||||
matchingSignRight = ")";
|
||||
currentMatchingLevel++;
|
||||
} else if (token == "[") {
|
||||
matchingSignLeft = "[";
|
||||
matchingSignRight = "]";
|
||||
currentMatchingLevel++;
|
||||
} else if (token == "<") {
|
||||
matchingSignLeft = "<";
|
||||
matchingSignRight = ">";
|
||||
currentMatchingLevel++;
|
||||
}
|
||||
} else {
|
||||
if (token == matchingSignLeft) {
|
||||
currentMatchingLevel++;
|
||||
} else if (token == matchingSignRight) {
|
||||
currentMatchingLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ownerExpression;
|
||||
if (lastMemberOperatorPos<0) {
|
||||
memberOperator = "";
|
||||
memberExpression = expression;
|
||||
} else {
|
||||
memberOperator = expression[lastMemberOperatorPos];
|
||||
memberExpression = expression.mid(lastMemberOperatorPos+1);
|
||||
ownerExpression = expression.mid(0,lastMemberOperatorPos);
|
||||
}
|
||||
if (memberExpression.length()>1) {
|
||||
memberExpression = memberExpression.mid(memberExpression.length()-1,1);
|
||||
}
|
||||
return ownerExpression;
|
||||
return getOwnerExpressionAndMember(expression,memberOperator,memberExpression);
|
||||
}
|
||||
|
||||
QStringList Editor::getExpressionAtPosition(
|
||||
|
@ -3099,21 +3055,9 @@ QString Editor::getParserHint(const QStringList& expression,const QString &s, in
|
|||
{
|
||||
// This piece of code changes the parser database, possibly making hints and code completion invalid...
|
||||
QString result;
|
||||
PStatement statement;
|
||||
if (expression.count()>1) {
|
||||
PEvalStatement evalStatement = mParser->evalExpression(
|
||||
PStatement statement = mParser->findStatementOf(
|
||||
mFilename,expression,
|
||||
mParser->findAndScanBlockAt(mFilename,line));
|
||||
if (evalStatement) {
|
||||
if (evalStatement->kind == EvalStatementKind::Type) {
|
||||
statement = evalStatement->effectiveTypeStatement;
|
||||
} else {
|
||||
statement = evalStatement->baseStatement;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
statement = mParser->findStatementOf(mFilename, s, line);
|
||||
}
|
||||
if (!statement)
|
||||
return result;
|
||||
if (statement->kind == StatementKind::skFunction
|
||||
|
|
|
@ -199,6 +199,8 @@ public:
|
|||
QString& memberOperator,
|
||||
QStringList& memberExpression);
|
||||
QString getWordForCompletionSearch(const BufferCoord& pos,bool permitTilde);
|
||||
QStringList getExpressionAtPosition(
|
||||
const BufferCoord& pos);
|
||||
|
||||
const PCppParser &parser();
|
||||
|
||||
|
@ -260,8 +262,6 @@ private:
|
|||
void popUserCodeInTabStops();
|
||||
void onExportedFormatToken(PSynHighlighter syntaxHighlighter, int Line, int column, const QString& token,
|
||||
PSynHighlighterAttribute &attr);
|
||||
QStringList getExpressionAtPosition(
|
||||
const BufferCoord& pos);
|
||||
private:
|
||||
QByteArray mEncodingOption; // the encoding type set by the user
|
||||
QByteArray mFileEncoding; // the real encoding of the file (auto detected)
|
||||
|
|
|
@ -39,11 +39,6 @@ CppParser::CppParser(QObject *parent) : QObject(parent)
|
|||
//mBlockBeginSkips;
|
||||
//mBlockEndSkips;
|
||||
//mInlineNamespaceEndSkips;
|
||||
mMemberOperators.insert(".");
|
||||
mMemberOperators.insert("::");
|
||||
mMemberOperators.insert("->");
|
||||
mMemberOperators.insert("->*");
|
||||
mMemberOperators.insert(".*");
|
||||
}
|
||||
|
||||
CppParser::~CppParser()
|
||||
|
@ -420,6 +415,38 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
|
|||
return findStatementOf(fileName,phrase,currentClass,statementParentType,force);
|
||||
}
|
||||
|
||||
PStatement CppParser::findStatementOf(const QString &fileName, const QStringList &expression, const PStatement ¤tScope)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mParsing)
|
||||
return PStatement();
|
||||
QString memberOperator;
|
||||
QStringList memberExpression;
|
||||
QStringList ownerExpression = getOwnerExpressionAndMember(expression,memberOperator,memberExpression);
|
||||
if (memberExpression.isEmpty()) {
|
||||
return PStatement();
|
||||
}
|
||||
QString phrase = memberExpression[0];
|
||||
if (memberOperator.isEmpty()) {
|
||||
return findStatementStartingFrom(fileName,phrase,currentScope);
|
||||
} else if (ownerExpression.isEmpty()) {
|
||||
return findMemberOfStatement(phrase,PStatement());
|
||||
} else {
|
||||
int pos = 0;
|
||||
PEvalStatement ownerEvalStatement = doEvalExpression(fileName,
|
||||
ownerExpression,
|
||||
pos,
|
||||
currentScope,
|
||||
PEvalStatement(),
|
||||
true);
|
||||
if (!ownerEvalStatement) {
|
||||
return PStatement();
|
||||
}
|
||||
return findMemberOfStatement(phrase, ownerEvalStatement->effectiveTypeStatement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope)
|
||||
{
|
||||
PStatement scopeStatement = startScope;
|
||||
|
@ -4608,10 +4635,7 @@ void CppParser::updateSerialId()
|
|||
mSerialId = QString("%1 %2").arg(mParserId).arg(mSerialCount);
|
||||
}
|
||||
|
||||
bool CppParser::isMemberOperator(QString token) const
|
||||
{
|
||||
return mMemberOperators.contains(token);
|
||||
}
|
||||
|
||||
|
||||
const StatementModel &CppParser::statementList() const
|
||||
{
|
||||
|
|
|
@ -49,6 +49,10 @@ public:
|
|||
const QString& phrase,
|
||||
const PStatement& currentClass,
|
||||
bool force = false);
|
||||
|
||||
PStatement findStatementOf(const QString& fileName,
|
||||
const QStringList& expression,
|
||||
const PStatement& currentScope);
|
||||
/**
|
||||
* @brief evaluate the expression
|
||||
* @param fileName
|
||||
|
@ -86,13 +90,6 @@ public:
|
|||
|
||||
QString prettyPrintStatement(const PStatement& statement, const QString& filename, int line = -1);
|
||||
|
||||
/**
|
||||
* @brief test if the token is a member/scope operator
|
||||
* @param token
|
||||
* @return true if it is, false if not
|
||||
*/
|
||||
bool isMemberOperator(QString token) const;
|
||||
|
||||
bool enabled() const;
|
||||
void setEnabled(bool newEnabled);
|
||||
|
||||
|
@ -452,7 +449,6 @@ private:
|
|||
GetFileStreamCallBack mOnGetFileStream;
|
||||
QMap<QString,SkipType> mCppKeywords;
|
||||
QSet<QString> mCppTypeKeywords;
|
||||
QSet<QString> mMemberOperators;
|
||||
};
|
||||
using PCppParser = std::shared_ptr<CppParser>;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ QSet<QString> CKeywords;
|
|||
QSet<QString> STLPointers;
|
||||
QSet<QString> STLContainers;
|
||||
QSet<QString> STLElementMethods;
|
||||
QSet<QString> MemberOperators;
|
||||
|
||||
Q_GLOBAL_STATIC(QSet<QString>,CppHeaderExts)
|
||||
Q_GLOBAL_STATIC(QSet<QString>,CppSourceExts)
|
||||
|
@ -293,6 +294,12 @@ void initParser()
|
|||
JavadocTags.append("@throws");
|
||||
JavadocTags.append("@value");
|
||||
JavadocTags.append("@version");
|
||||
|
||||
MemberOperators.insert(".");
|
||||
MemberOperators.insert("::");
|
||||
MemberOperators.insert("->");
|
||||
MemberOperators.insert("->*");
|
||||
MemberOperators.insert(".*");
|
||||
}
|
||||
|
||||
QString getHeaderFilename(const QString &relativeTo, const QString &line,
|
||||
|
@ -520,3 +527,58 @@ void EvalStatement::assignType(const PEvalStatement &typeStatement)
|
|||
pointerLevel = typeStatement->pointerLevel;
|
||||
effectiveTypeStatement = typeStatement->effectiveTypeStatement;
|
||||
}
|
||||
|
||||
QStringList getOwnerExpressionAndMember(const QStringList expression, QString &memberOperator, QStringList &memberExpression)
|
||||
{
|
||||
//find position of the last member operator
|
||||
int lastMemberOperatorPos = -1;
|
||||
int currentMatchingLevel = 0;
|
||||
QString matchingSignLeft;
|
||||
QString matchingSignRight;
|
||||
for (int i=0;i<expression.length();i++) {
|
||||
QString token = expression[i];
|
||||
if (currentMatchingLevel == 0) {
|
||||
if (isMemberOperator(token)) {
|
||||
lastMemberOperatorPos = i;
|
||||
} else if (token == "(") {
|
||||
matchingSignLeft = "(";
|
||||
matchingSignRight = ")";
|
||||
currentMatchingLevel++;
|
||||
} else if (token == "[") {
|
||||
matchingSignLeft = "[";
|
||||
matchingSignRight = "]";
|
||||
currentMatchingLevel++;
|
||||
} else if (token == "<") {
|
||||
matchingSignLeft = "<";
|
||||
matchingSignRight = ">";
|
||||
currentMatchingLevel++;
|
||||
}
|
||||
} else {
|
||||
if (token == matchingSignLeft) {
|
||||
currentMatchingLevel++;
|
||||
} else if (token == matchingSignRight) {
|
||||
currentMatchingLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ownerExpression;
|
||||
if (lastMemberOperatorPos<0) {
|
||||
memberOperator = "";
|
||||
memberExpression = expression;
|
||||
} else {
|
||||
memberOperator = expression[lastMemberOperatorPos];
|
||||
memberExpression = expression.mid(lastMemberOperatorPos+1);
|
||||
ownerExpression = expression.mid(0,lastMemberOperatorPos);
|
||||
}
|
||||
if (memberExpression.length()>1) {
|
||||
memberExpression = memberExpression.mid(memberExpression.length()-1,1);
|
||||
}
|
||||
return ownerExpression;
|
||||
|
||||
}
|
||||
|
||||
bool isMemberOperator(QString token)
|
||||
{
|
||||
return MemberOperators.contains(token);
|
||||
}
|
||||
|
|
|
@ -225,6 +225,7 @@ extern QSet<QString> CppTypeKeywords;
|
|||
extern QSet<QString> STLPointers;
|
||||
extern QSet<QString> STLContainers;
|
||||
extern QSet<QString> STLElementMethods;
|
||||
extern QSet<QString> MemberOperators;
|
||||
|
||||
void initParser();
|
||||
|
||||
|
@ -240,5 +241,10 @@ bool isCfile(const QString& filename);
|
|||
bool isKeyword(const QString& word);
|
||||
bool isScopeTypeKind(StatementKind kind);
|
||||
MemberOperatorType getOperatorType(const QString& phrase, int index);
|
||||
QStringList getOwnerExpressionAndMember(
|
||||
const QStringList expression,
|
||||
QString& memberOperator,
|
||||
QStringList& memberExpression);
|
||||
bool isMemberOperator(QString token);
|
||||
|
||||
#endif // PARSER_UTILS_H
|
||||
|
|
Loading…
Reference in New Issue