missing brackets highlight

This commit is contained in:
Zira project 2019-12-21 17:23:38 +05:00
parent 48e1fee528
commit 1240dbaeb2
11 changed files with 204 additions and 27 deletions

View File

@ -90,6 +90,7 @@ public:
void resetExtraSelections();
void setParseError(bool error);
bool getParseError();
void highlightError(int pos, int length);
protected:
void focusInEvent(QFocusEvent *e) override;
void focusOutEvent(QFocusEvent *e) override;
@ -101,6 +102,7 @@ protected:
bool event(QEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void clearTextHoverFormat();
void clearErrorsFormat();
void insertFromMimeData(const QMimeData *source) override;
void updateWidgetsGeometry();
void setTabsSettings();
@ -319,6 +321,7 @@ private:
bool parseCSSEnabled;
QColor unusedVariableColor;
QList<QTextEdit::ExtraSelection> wordsExtraSelections;
QList<QTextEdit::ExtraSelection> errorsExtraSelections;
bool experimentalMode;
signals:
void ready(int index);

View File

@ -19,6 +19,8 @@ public:
virtual int getLine(QString & text, int offset);
virtual QString getLineText(QString & text, int offset);
virtual int getFirstNotEmptyLineTo(QString & text, int offset);
virtual int findOpenScope(QVector<int> list);
virtual int findCloseScope(QVector<int> list);
protected:
QRegularExpression stringDQExpression;
QRegularExpression stringSQExpression;

View File

@ -44,6 +44,7 @@ public:
struct ParseResultError {
QString text;
int line;
int symbol;
};
struct ParseResult
{
@ -70,7 +71,7 @@ protected:
void addKeyframe(QString name, int line);
void addFont(QString name, int line);
void addComment(QString text, int line);
void addError(QString text, int line);
void addError(QString text, int line, int symbol);
void parseCode(QString & code, QString & origText);
private:
ParseCSS::ParseResult result;

View File

@ -57,6 +57,7 @@ public:
struct ParseResultError {
QString text;
int line;
int symbol;
};
struct ParseResult
{
@ -81,7 +82,7 @@ protected:
void updateVariableType(QString clsName, QString funcName, QString varName, QString type);
void addConstant(QString clsName, QString funcName, QString name, QString value, int line);
void addComment(QString text, int line);
void addError(QString text, int line);
void addError(QString text, int line, int symbol);
QRegularExpression commentSLExpression;
QRegularExpression regexpExpression;

View File

@ -80,6 +80,7 @@ public:
struct ParseResultError {
QString text;
int line;
int symbol;
};
struct ParseResult
{
@ -112,7 +113,7 @@ protected:
void updateVariableType(QString clsName, QString funcName, QString varName, QString type);
void addConstant(QString clsName, QString name, QString value, int line);
void addComment(QString text, int line);
void addError(QString text, int line);
void addError(QString text, int line, int symbol);
QRegularExpression phpExpression;
QRegularExpression phpStartExpression;

View File

@ -968,6 +968,29 @@ void Editor::clearTextHoverFormat()
}
}
void Editor::clearErrorsFormat()
{
if (errorsExtraSelections.size() > 0) {
errorsExtraSelections.clear();
highlightExtras();
}
}
void Editor::highlightError(int pos, int length)
{
if (pos < 0) return;
// show wave underline
QTextCursor cursor = textCursor();
cursor.setPosition(pos);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, length);
QTextEdit::ExtraSelection errorSelection;
errorSelection.format.setUnderlineColor(lineErrorColor);
errorSelection.format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
errorSelection.cursor = cursor;
errorsExtraSelections.append(errorSelection);
highlightExtras();
}
void Editor::updateSizes()
{
updateViewportMargins();
@ -4766,6 +4789,11 @@ void Editor::highlightExtras(QChar prevChar, QChar nextChar, QChar cursorTextPre
for (int i=0; i<wordsExtraSelections.size(); i++) {
extraSelections.append(wordsExtraSelections.at(i));
}
// errors
for (int i=0; i<errorsExtraSelections.size(); i++) {
extraSelections.append(errorsExtraSelections.at(i));
}
}
setExtraSelections(extraSelections);
}
@ -4787,6 +4815,7 @@ void Editor::clearErrors()
static_cast<LineMap *>(lineMap)->clearErrors();
static_cast<LineMark *>(lineMark)->clearErrors();
breadcrumbs->setToolTip("");
clearErrorsFormat();
}
void Editor::setError(int line, QString text)

View File

@ -1384,6 +1384,7 @@ void MainWindow::parseMixedFinished(int tabIndex, ParsePHP::ParseResult result)
for (int i=0; i<result.errors.size(); i++) {
ParsePHP::ParseResultError error = result.errors.at(i);
textEditor->setError(error.line, error.text);
textEditor->highlightError(error.symbol, 1);
}
}
textEditor->updateMarksAndMapArea();
@ -1403,6 +1404,7 @@ void MainWindow::parseJSFinished(int tabIndex, ParseJS::ParseResult result)
for (int i=0; i<result.errors.size(); i++) {
ParseJS::ParseResultError error = result.errors.at(i);
textEditor->setError(error.line, error.text);
textEditor->highlightError(error.symbol, 1);
}
}
textEditor->updateMarksAndMapArea();
@ -1421,6 +1423,7 @@ void MainWindow::parseCSSFinished(int tabIndex, ParseCSS::ParseResult result)
for (int i=0; i<result.errors.size(); i++) {
ParseCSS::ParseResultError error = result.errors.at(i);
textEditor->setError(error.line, error.text);
textEditor->highlightError(error.symbol, 1);
}
}
textEditor->updateMarksAndMapArea();

View File

@ -6,6 +6,7 @@
#include "parse.h"
#include "helper.h"
#include <QVector>
Parse::Parse()
{
@ -69,3 +70,37 @@ int Parse::getFirstNotEmptyLineTo(QString & text, int offset)
}
return line;
}
int Parse::findOpenScope(QVector<int> list)
{
int s = 0;
for (int i=list.size()-1; i>=0; i--) {
int v = list.at(i);
if (v < 0) {
s--;
} else if (v > 0) {
s++;
}
if (s > 0) {
return v;
}
}
return !list.isEmpty() ? list.last() : 0;
}
int Parse::findCloseScope(QVector<int> list)
{
int s = 0;
for (int i=0; i<list.size(); i++) {
int v = list.at(i);
if (v > 0) {
s++;
} else if (v < 0) {
s--;
}
if (s < 0) {
return v;
}
}
return !list.isEmpty() ? list.last() : 0;
}

View File

@ -180,10 +180,11 @@ void ParseCSS::addComment(QString text, int line) {
result.comments.append(comment);
}
void ParseCSS::addError(QString text, int line) {
void ParseCSS::addError(QString text, int line, int symbol) {
ParseResultError error;
error.text = text;
error.line = line;
error.symbol = symbol;
result.errors.append(error);
}
@ -199,6 +200,7 @@ void ParseCSS::parseCode(QString & code, QString & origText)
int selectorScope = -1, mediaScope = -1, keyframeScope = -1, fontScope = -1;
int pars = 0;
int curlyBrackets = 0, roundBrackets = 0, squareBrackets = 0;
QVector<int> curlyBracketsList, roundBracketsList, squareBracketsList;
int mediaArgPars = -1;
int mediaArgsStart = -1;
int fontFamilyStart = -1;
@ -311,11 +313,13 @@ void ParseCSS::parseCode(QString & code, QString & origText)
if (k == "{") {
scope++;
curlyBrackets++;
curlyBracketsList.append(m.capturedStart(1)+1);
}
if (k == "}") {
scope--;
if (scope < 0) scope = 0;
curlyBrackets--;
curlyBracketsList.append(-1 * (m.capturedStart(1)+1));
// selector close
if (current_selector.size() > 0 && selectorScope >= 0 && selectorScope == scope) {
current_selector = "";
@ -341,11 +345,13 @@ void ParseCSS::parseCode(QString & code, QString & origText)
if (k == "(") {
pars++;
roundBrackets++;
roundBracketsList.append(m.capturedStart(1)+1);
}
if (k == ")") {
pars--;
if (pars < 0) pars = 0;
roundBrackets--;
roundBracketsList.append(-1 * (m.capturedStart(1)+1));
// media args
if (mediaArgPars >= 0 && mediaArgPars == pars && mediaArgsStart >= 0 && expectName.size() == 0) {
expectName = origText.mid(mediaArgsStart+1, m.capturedStart(1)-mediaArgsStart-1).trimmed().replace(QRegularExpression("[\\s]+"), " ");
@ -356,9 +362,11 @@ void ParseCSS::parseCode(QString & code, QString & origText)
// brackets
if (k == "[") {
squareBrackets++;
squareBracketsList.append(m.capturedStart(1)+1);
}
if (k == "]") {
squareBrackets--;
squareBracketsList.append(-1 * (m.capturedStart(1)+1));
}
prevPrevPrevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevPrevPrevK;
prevPrevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevPrevK;
@ -370,13 +378,39 @@ void ParseCSS::parseCode(QString & code, QString & origText)
prevPrevK = prevK;
prevK = k;
}
int line = origText.count("\n") + 1;
if (curlyBrackets > 0) addError(QObject::tr("Unclosed brace"), line);
else if (curlyBrackets < 0) addError(QObject::tr("Excess brace"), line);
if (roundBrackets > 0) addError(QObject::tr("Unclosed parenthesis"), line);
else if (roundBrackets < 0) addError(QObject::tr("Excess parenthesis"), line);
if (squareBrackets > 0) addError(QObject::tr("Unclosed bracket"), line);
else if (squareBrackets < 0) addError(QObject::tr("Excess bracket"), line);
if (curlyBrackets > 0) {
int offset = findOpenScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed brace"), line, offset);
} else if (curlyBrackets < 0) {
int offset = findCloseScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess brace"), line, offset);
}
if (roundBrackets > 0) {
int offset = findOpenScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed parenthesis"), line, offset);
} else if (roundBrackets < 0) {
int offset = findCloseScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess parenthesis"), line, offset);
}
if (squareBrackets > 0) {
int offset = findOpenScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed bracket"), line, offset);
} else if (squareBrackets < 0) {
int offset = findCloseScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess bracket"), line, offset);
}
}
void ParseCSS::reset()

View File

@ -263,10 +263,11 @@ void ParseJS::addComment(QString text, int line) {
result.comments.append(comment);
}
void ParseJS::addError(QString text, int line) {
void ParseJS::addError(QString text, int line, int symbol) {
ParseResultError error;
error.text = text;
error.line = line;
error.symbol = symbol;
result.errors.append(error);
}
@ -290,6 +291,7 @@ void ParseJS::parseCode(QString & code, QString & origText)
int functionScope = -1;
int pars = 0;
int curlyBrackets = 0, roundBrackets = 0, squareBrackets = 0;
QVector<int> curlyBracketsList, roundBracketsList, squareBracketsList;
int functionArgPars = -1;
int functionArgsStart = -1;
int constantValueStart = -1;
@ -554,11 +556,13 @@ void ParseJS::parseCode(QString & code, QString & origText)
if (k == "{") {
scope++;
curlyBrackets++;
curlyBracketsList.append(m.capturedStart(1)+1);
}
if (k == "}") {
scope--;
if (scope < 0) scope = 0;
curlyBrackets--;
curlyBracketsList.append(-1 * (m.capturedStart(1)+1));
// function close
if (current_function.size() > 0 && functionScope >= 0 && functionScope == scope) {
current_function = "";
@ -580,11 +584,13 @@ void ParseJS::parseCode(QString & code, QString & origText)
if (k == "(") {
pars++;
roundBrackets++;
roundBracketsList.append(m.capturedStart(1)+1);
}
if (k == ")") {
pars--;
if (pars < 0) pars = 0;
roundBrackets--;
roundBracketsList.append(-1 * (m.capturedStart(1)+1));
// function args
if (functionArgPars >= 0 && functionArgPars == pars && functionArgsStart >= 0) {
current_function_args = origText.mid(functionArgsStart+1, m.capturedStart(1)-functionArgsStart-1).trimmed();
@ -626,9 +632,11 @@ void ParseJS::parseCode(QString & code, QString & origText)
// brackets
if (k == "[") {
squareBrackets++;
squareBracketsList.append(m.capturedStart(1)+1);
}
if (k == "]") {
squareBrackets--;
squareBracketsList.append(-1 * (m.capturedStart(1)+1));
}
prevPrevPrevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevPrevPrevK;
prevPrevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevPrevK;
@ -640,13 +648,39 @@ void ParseJS::parseCode(QString & code, QString & origText)
prevPrevK = prevK;
prevK = k;
}
int line = origText.count("\n") + 1;
if (curlyBrackets > 0) addError(QObject::tr("Unclosed brace"), line);
else if (curlyBrackets < 0) addError(QObject::tr("Excess brace"), line);
if (roundBrackets > 0) addError(QObject::tr("Unclosed parenthesis"), line);
else if (roundBrackets < 0) addError(QObject::tr("Excess parenthesis"), line);
if (squareBrackets > 0) addError(QObject::tr("Unclosed bracket"), line);
else if (squareBrackets < 0) addError(QObject::tr("Excess bracket"), line);
if (curlyBrackets > 0) {
int offset = findOpenScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed brace"), line, offset);
} else if (curlyBrackets < 0) {
int offset = findCloseScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess brace"), line, offset);
}
if (roundBrackets > 0) {
int offset = findOpenScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed parenthesis"), line, offset);
} else if (roundBrackets < 0) {
int offset = findCloseScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess parenthesis"), line, offset);
}
if (squareBrackets > 0) {
int offset = findOpenScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Unclosed bracket"), line, offset);
} else if (squareBrackets < 0) {
int offset = findCloseScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, offset);
addError(QObject::tr("Excess bracket"), line, offset);
}
}
void ParseJS::reset()

View File

@ -470,10 +470,11 @@ void ParsePHP::addComment(QString text, int line) {
result.comments.append(comment);
}
void ParsePHP::addError(QString text, int line) {
void ParsePHP::addError(QString text, int line, int symbol) {
ParseResultError error;
error.text = text;
error.line = line;
error.symbol = symbol;
result.errors.append(error);
}
@ -513,6 +514,7 @@ void ParsePHP::parseCode(QString & code, QString & origText, int textOffset)
int namespaceScope = -1, classScope = -1, interfaceScope = -1, traitScope = -1, functionScope = -1, anonymFunctionScope = -1, anonymClassScope = -1;
int pars = 0;
int curlyBrackets = 0, roundBrackets = 0, squareBrackets = 0;
QVector<int> curlyBracketsList, roundBracketsList, squareBracketsList;
int functionArgPars = -1;
int functionArgsStart = -1;
int constantValueStart = -1;
@ -1240,11 +1242,13 @@ void ParsePHP::parseCode(QString & code, QString & origText, int textOffset)
if (k == "{") {
scope++;
curlyBrackets++;
curlyBracketsList.append(m.capturedStart(1)+1);
}
if (k == "}") {
scope--;
if (scope < 0) scope = 0;
curlyBrackets--;
curlyBracketsList.append(-1 * (m.capturedStart(1)+1));
// namespace close
if (current_namespace.size() > 0 && namespaceScope >= 0 && namespaceScope == scope) {
current_namespace = "";
@ -1324,11 +1328,13 @@ void ParsePHP::parseCode(QString & code, QString & origText, int textOffset)
if (k == "(") {
pars++;
roundBrackets++;
roundBracketsList.append(m.capturedStart(1)+1);
}
if (k == ")") {
pars--;
if (pars < 0) pars = 0;
roundBrackets--;
roundBracketsList.append(-1 * (m.capturedStart(1)+1));
// function args
if (functionArgPars >= 0 && functionArgPars == pars && functionArgsStart >= 0) {
current_function_args = origText.mid(textOffset+functionArgsStart+1, m.capturedStart(1)-functionArgsStart-1).trimmed();
@ -1392,9 +1398,11 @@ void ParsePHP::parseCode(QString & code, QString & origText, int textOffset)
// brackets
if (k == "[") {
squareBrackets++;
squareBracketsList.append(m.capturedStart(1)+1);
}
if (k == "]") {
squareBrackets--;
squareBracketsList.append(-1 * (m.capturedStart(1)+1));
}
prevPrevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevPrevK;
prevPrevPrevPrevPrevPrevPrevK = prevPrevPrevPrevPrevPrevK;
@ -1405,13 +1413,39 @@ void ParsePHP::parseCode(QString & code, QString & origText, int textOffset)
prevPrevK = prevK;
prevK = k;
}
int line = origText.count("\n") + 1;
if (curlyBrackets > 0) addError(QObject::tr("Unclosed brace"), line);
else if (curlyBrackets < 0) addError(QObject::tr("Excess brace"), line);
if (roundBrackets > 0) addError(QObject::tr("Unclosed parenthesis"), line);
else if (roundBrackets < 0) addError(QObject::tr("Excess parenthesis"), line);
if (squareBrackets > 0) addError(QObject::tr("Unclosed bracket"), line);
else if (squareBrackets < 0) addError(QObject::tr("Excess bracket"), line);
if (curlyBrackets > 0) {
int offset = findOpenScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Unclosed brace"), line, textOffset + offset);
} else if (curlyBrackets < 0) {
int offset = findCloseScope(curlyBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Excess brace"), line, textOffset + offset);
}
if (roundBrackets > 0) {
int offset = findOpenScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Unclosed parenthesis"), line, textOffset + offset);
} else if (roundBrackets < 0) {
int offset = findCloseScope(roundBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Excess parenthesis"), line, textOffset + offset);
}
if (squareBrackets > 0) {
int offset = findOpenScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Unclosed bracket"), line, textOffset + offset);
} else if (squareBrackets < 0) {
int offset = findCloseScope(squareBracketsList);
if (offset != 0) offset = abs(offset) - 1;
int line = getLine(origText, textOffset + offset);
addError(QObject::tr("Excess bracket"), line, textOffset + offset);
}
}
void ParsePHP::reset()