- enhancement: use the new expression parser to implement rename symbol

- fix: rename symbol shouldn't remove empty lines
This commit is contained in:
Roy Qu 2021-12-19 10:16:46 +08:00
parent 109ea5a0ae
commit 33e8042944
6 changed files with 70 additions and 53 deletions

View File

@ -2,6 +2,8 @@ Version 0.11.3 For Dev-C++ 7 Beta
- fix: use pixel size for fonts, to fit different dpi in multiple displays
- enhancement: use the new expression parser to parse info for tips
- enhancement: better highlight processing for preprocess directives
- enhancement: use the new expression parser to implement rename symbol
- fix: rename symbol shouldn't remove empty lines
Version 0.11.2 For Dev-C++ 7 Beta
- fix: button "run all problem cases" not disabled when compiling or debugging

View File

@ -29,7 +29,7 @@ bool CppRefacter::findOccurence(Editor *editor, const BufferCoord &pos)
PStatement statement = editor->parser()->findStatementOf(
editor->filename(),
expression,
editor->parser()->findAndScanBlockAt(editor->filename(),pos.Line));
pos.Line);
// definition of the symbol not found
if (!statement)
return false;
@ -98,12 +98,11 @@ void CppRefacter::renameSymbol(Editor *editor, const BufferCoord &pos, const QSt
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 oldStatement = editor->parser()->findStatementOf(
editor->filename(),
phrase,
expression,
pos.Line);
QString oldScope = fullParentName(oldStatement);
// definition of the symbol not found
@ -118,10 +117,11 @@ void CppRefacter::renameSymbol(Editor *editor, const BufferCoord &pos, const QSt
return;
}
QString newPhrase = phrase.mid(0,phrase.length()-word.length()) + newWord;
QStringList newExpression = expression;
newExpression[newExpression.count()-1]=newWord;
PStatement newStatement = editor->parser()->findStatementOf(
editor->filename(),
newPhrase,
newExpression,
pos.Line);
if (newStatement && fullParentName(newStatement) == oldScope) {
QMessageBox::critical(editor,
@ -177,7 +177,7 @@ PSearchResultTreeItem CppRefacter::findOccurenceInFile(
parentItem->filename = filename;
parentItem->parent = nullptr;
QStringList buffer;
SynEdit editor;
Editor editor(nullptr);
if (pMainWindow->editorList()->getContentFromOpenedEditor(
filename,buffer)){
editor.lines()->setContents(buffer);
@ -204,28 +204,31 @@ PSearchResultTreeItem CppRefacter::findOccurenceInFile(
while (!editor.highlighter()->eol()) {
int start = editor.highlighter()->getTokenPos() + 1;
QString token = editor.highlighter()->getToken();
if (token == statement->command) {
//same name symbol , test if the same statement;
BufferCoord p,pBeginPos,pEndPos;
p.Line = posY+1;
p.Char = start;
QString phrase = getWordAtPosition(&editor, p, pBeginPos,pEndPos,
Editor::WordPurpose::wpInformation);
PStatement tokenStatement = parser->findStatementOf(
filename,
phrase, p.Line);
if (tokenStatement
&& (tokenStatement->line == statement->line)
&& (tokenStatement->fileName == statement->fileName)) {
PSearchResultTreeItem item = std::make_shared<SearchResultTreeItem>();
item->filename = filename;
item->line = p.Line;
item->start = start;
item->len = phrase.length();
item->parent = parentItem.get();
item->text = line;
item->text.replace('\t',' ');
parentItem->results.append(item);
PSynHighlighterAttribute attr = editor.highlighter()->getTokenAttribute();
if (!attr || attr!=editor.highlighter()->commentAttribute()) {
if (token == statement->command) {
//same name symbol , test if the same statement;
BufferCoord p;
p.Line = posY+1;
p.Char = start+1;
QStringList expression = editor.getExpressionAtPosition(p);
PStatement tokenStatement = parser->findStatementOf(
filename,
expression, p.Line);
if (tokenStatement
&& (tokenStatement->line == statement->line)
&& (tokenStatement->fileName == statement->fileName)) {
PSearchResultTreeItem item = std::make_shared<SearchResultTreeItem>();
item->filename = filename;
item->line = p.Line;
item->start = start;
item->len = token.length();
item->parent = parentItem.get();
item->text = line;
item->text.replace('\t',' ');
parentItem->results.append(item);
}
}
}
editor.highlighter()->next();
@ -238,7 +241,7 @@ PSearchResultTreeItem CppRefacter::findOccurenceInFile(
void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement &statement, const QString &newWord, const PCppParser &parser)
{
QStringList buffer;
SynEdit editor;
Editor editor(nullptr);
if (pMainWindow->editorList()->getContentFromOpenedEditor(
filename,buffer)){
editor.lines()->setContents(buffer);
@ -251,10 +254,6 @@ void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement &
int posY = 0;
while (posY < editor.lines()->count()) {
QString line = editor.lines()->getString(posY);
if (line.isEmpty()) {
posY++;
continue;
}
if (posY == 0) {
editor.highlighter()->resetState();
@ -269,14 +268,14 @@ void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement &
QString token = editor.highlighter()->getToken();
if (token == statement->command) {
//same name symbol , test if the same statement;
BufferCoord p,pBeginPos,pEndPos;
BufferCoord p;
p.Line = posY+1;
p.Char = start;
QString phrase = getWordAtPosition(&editor, p, pBeginPos,pEndPos,
Editor::WordPurpose::wpInformation);
p.Char = start+1;
QStringList expression = editor.getExpressionAtPosition(p);
PStatement tokenStatement = parser->findStatementOf(
filename,
phrase, p.Line);
expression, p.Line);
if (tokenStatement
&& (tokenStatement->line == statement->line)
&& (tokenStatement->fileName == statement->fileName)) {

View File

@ -1644,35 +1644,38 @@ QStringList Editor::getExpressionAtPosition(
int ch = pos.Char-1;
int symbolMatchingLevel = 0;
LastSymbolType lastSymbolType=LastSymbolType::None;
PSynHighlighter highlighter = highlighterManager.getHighlighter(mFilename);
if (!highlighter)
return result;
while (true) {
if (line>=lines()->count() || line<0)
break;
QStringList tokens;
if (line==0) {
highlighter()->resetState();
highlighter->resetState();
} else {
highlighter()->setState(lines()->ranges(line-1));
highlighter->setState(lines()->ranges(line-1));
}
QString sLine = lines()->getString(line);
highlighter()->setLine(sLine,line-1);
while (!highlighter()->eol()) {
int start = highlighter()->getTokenPos() + 1;
QString token = highlighter()->getToken();
highlighter->setLine(sLine,line-1);
while (!highlighter->eol()) {
int start = highlighter->getTokenPos();
QString token = highlighter->getToken();
int endPos = start + token.length()-1;
if (start>ch) {
break;
}
PSynHighlighterAttribute attr = highlighter()->getTokenAttribute();
PSynHighlighterAttribute attr = highlighter->getTokenAttribute();
if ( (line == pos.Line-1)
&& (start<=ch) && (ch<=endPos)) {
if (attr==highlighter()->commentAttribute() || attr == highlighter()->stringAttribute()) {
if (attr==highlighter->commentAttribute() || attr == highlighter->stringAttribute()) {
return result;
}
}
if (attr!=highlighter()->commentAttribute() && attr!=highlighter()->whitespaceAttribute()){
if (attr!=highlighter->commentAttribute() && attr!=highlighter->whitespaceAttribute()){
tokens.append(token);
}
highlighter()->next();
highlighter->next();
}
for (int i=tokens.count()-1;i>=0;i--) {
QString token = tokens[i];
@ -3057,7 +3060,7 @@ QString Editor::getParserHint(const QStringList& expression,const QString &s, in
QString result;
PStatement statement = mParser->findStatementOf(
mFilename,expression,
mParser->findAndScanBlockAt(mFilename,line));
line);
if (!statement)
return result;
if (statement->kind == StatementKind::skFunction

View File

@ -5116,12 +5116,11 @@ void MainWindow::on_actionRename_Symbol_triggered()
BufferCoord oldCaretXY = editor->caretXY();
if (editor->inProject() && mProject) {
mProject->cppParser()->parseFileList();
BufferCoord pBeginPos,pEndPos;
QString phrase = getWordAtPosition(editor,oldCaretXY,pBeginPos,pEndPos,Editor::WordPurpose::wpInformation);
QStringList expression = editor->getExpressionAtPosition(oldCaretXY);
// Find it's definition
PStatement oldStatement = editor->parser()->findStatementOf(
editor->filename(),
phrase,
expression,
oldCaretXY.Line);
// definition of the symbol not found
if (!oldStatement)

View File

@ -246,6 +246,8 @@ PStatement CppParser::findStatement(const QString &fullname)
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, int line)
{
QMutexLocker locker(&mMutex);
if (mParsing)
return PStatement();
return findStatementOf(fileName,phrase,findAndScanBlockAt(fileName,line));
}
@ -447,6 +449,14 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QStringList
}
PStatement CppParser::findStatementOf(const QString &fileName, const QStringList &expression, int line)
{
QMutexLocker locker(&mMutex);
if (mParsing)
return PStatement();
return findStatementOf(fileName,expression,findAndScanBlockAt(fileName,line));
}
PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope)
{
PStatement scopeStatement = startScope;

View File

@ -53,6 +53,10 @@ public:
PStatement findStatementOf(const QString& fileName,
const QStringList& expression,
const PStatement& currentScope);
PStatement findStatementOf(const QString& fileName,
const QStringList& expression,
int line);
/**
* @brief evaluate the expression
* @param fileName