summaryrefslogtreecommitdiffstats
path: root/scintilla/lexers/LexSQL.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'scintilla/lexers/LexSQL.cxx')
-rw-r--r--scintilla/lexers/LexSQL.cxx162
1 files changed, 131 insertions, 31 deletions
diff --git a/scintilla/lexers/LexSQL.cxx b/scintilla/lexers/LexSQL.cxx
index 6d97789..6a024e5 100644
--- a/scintilla/lexers/LexSQL.cxx
+++ b/scintilla/lexers/LexSQL.cxx
@@ -62,6 +62,7 @@ static inline bool IsANumberChar(int ch) {
ch == '.' || ch == '-' || ch == '+');
}
+typedef unsigned int sql_state_t;
class SQLStates {
public :
@@ -69,7 +70,7 @@ public :
sqlStatement.Set(lineNumber, sqlStatesLine);
}
- unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
+ sql_state_t IgnoreWhen (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_IGNORE_WHEN;
else
@@ -78,7 +79,7 @@ public :
return sqlStatesLine;
}
- unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) {
+ sql_state_t IntoCondition (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_CONDITION;
else
@@ -87,7 +88,7 @@ public :
return sqlStatesLine;
}
- unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) {
+ sql_state_t IntoExceptionBlock (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_EXCEPTION;
else
@@ -96,7 +97,7 @@ public :
return sqlStatesLine;
}
- unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) {
+ sql_state_t IntoDeclareBlock (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_DECLARE;
else
@@ -105,7 +106,7 @@ public :
return sqlStatesLine;
}
- unsigned short int IntoMergeStatement (unsigned short int sqlStatesLine, bool enable) {
+ sql_state_t IntoMergeStatement (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_MERGE_STATEMENT;
else
@@ -114,7 +115,7 @@ public :
return sqlStatesLine;
}
- unsigned short int CaseMergeWithoutWhenFound (unsigned short int sqlStatesLine, bool found) {
+ sql_state_t CaseMergeWithoutWhenFound (sql_state_t sqlStatesLine, bool found) {
if (found)
sqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
else
@@ -122,7 +123,7 @@ public :
return sqlStatesLine;
}
- unsigned short int IntoSelectStatementOrAssignment (unsigned short int sqlStatesLine, bool found) {
+ sql_state_t IntoSelectStatementOrAssignment (sql_state_t sqlStatesLine, bool found) {
if (found)
sqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
else
@@ -130,67 +131,109 @@ public :
return sqlStatesLine;
}
- unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
+ sql_state_t BeginCaseBlock (sql_state_t sqlStatesLine) {
if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
sqlStatesLine++;
}
return sqlStatesLine;
}
- unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) {
+ sql_state_t EndCaseBlock (sql_state_t sqlStatesLine) {
if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
sqlStatesLine--;
}
return sqlStatesLine;
}
- bool IsIgnoreWhen (unsigned short int sqlStatesLine) {
+ sql_state_t IntoCreateStatement (sql_state_t sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_CREATE;
+ else
+ sqlStatesLine &= ~MASK_INTO_CREATE;
+
+ return sqlStatesLine;
+ }
+
+ sql_state_t IntoCreateViewStatement (sql_state_t sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_CREATE_VIEW;
+ else
+ sqlStatesLine &= ~MASK_INTO_CREATE_VIEW;
+
+ return sqlStatesLine;
+ }
+
+ sql_state_t IntoCreateViewAsStatement (sql_state_t sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_CREATE_VIEW_AS_STATEMENT;
+ else
+ sqlStatesLine &= ~MASK_INTO_CREATE_VIEW_AS_STATEMENT;
+
+ return sqlStatesLine;
+ }
+
+ bool IsIgnoreWhen (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
}
- bool IsIntoCondition (unsigned short int sqlStatesLine) {
+ bool IsIntoCondition (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
}
- bool IsIntoCaseBlock (unsigned short int sqlStatesLine) {
+ bool IsIntoCaseBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_NESTED_CASES) != 0;
}
- bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
+ bool IsIntoExceptionBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
}
- bool IsIntoSelectStatementOrAssignment (unsigned short int sqlStatesLine) {
+ bool IsIntoSelectStatementOrAssignment (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0;
}
- bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) {
+ bool IsCaseMergeWithoutWhenFound (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
}
- bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
+ bool IsIntoDeclareBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
}
- bool IsIntoMergeStatement (unsigned short int sqlStatesLine) {
+ bool IsIntoMergeStatement (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_MERGE_STATEMENT) != 0;
}
- unsigned short int ForLine(int lineNumber) {
+ bool IsIntoCreateStatement (sql_state_t sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_CREATE) != 0;
+ }
+
+ bool IsIntoCreateViewStatement (sql_state_t sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_CREATE_VIEW) != 0;
+ }
+
+ bool IsIntoCreateViewAsStatement (sql_state_t sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_CREATE_VIEW_AS_STATEMENT) != 0;
+ }
+
+ sql_state_t ForLine(int lineNumber) {
return sqlStatement.ValueAt(lineNumber);
}
SQLStates() {}
private :
- SparseState <unsigned short int> sqlStatement;
+ SparseState <sql_state_t> sqlStatement;
enum {
- MASK_NESTED_CASES = 0x01FF,
- MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x0200,
- MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x0400,
- MASK_MERGE_STATEMENT = 0x0800,
- MASK_INTO_DECLARE = 0x1000,
- MASK_INTO_EXCEPTION = 0x2000,
- MASK_INTO_CONDITION = 0x4000,
- MASK_IGNORE_WHEN = 0x8000
+ MASK_NESTED_CASES = 0x0001FF,
+ MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x000200,
+ MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x000400,
+ MASK_MERGE_STATEMENT = 0x000800,
+ MASK_INTO_DECLARE = 0x001000,
+ MASK_INTO_EXCEPTION = 0x002000,
+ MASK_INTO_CONDITION = 0x004000,
+ MASK_IGNORE_WHEN = 0x008000,
+ MASK_INTO_CREATE = 0x010000,
+ MASK_INTO_CREATE_VIEW = 0x020000,
+ MASK_INTO_CREATE_VIEW_AS_STATEMENT = 0x040000
};
};
@@ -561,12 +604,46 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (lineCurrent > 0) {
// Backtrack to previous line in case need to fix its fold status for folding block of single-line comments (i.e. '--').
- lineCurrent -= 1;
- startPos = styler.LineStart(lineCurrent);
-
+ int lastNLPos = -1;
+ // And keep going back until we find an operator ';' followed
+ // by white-space and/or comments. This will improve folding.
+ while (--startPos > 0) {
+ char ch = styler[startPos];
+ if (ch == '\n' || (ch == '\r' && styler[startPos + 1] != '\n')) {
+ lastNLPos = startPos;
+ } else if (ch == ';' &&
+ styler.StyleAt(startPos) == SCE_SQL_OPERATOR) {
+ bool isAllClear = true;
+ for (int tempPos = startPos + 1;
+ tempPos < lastNLPos;
+ ++tempPos) {
+ int tempStyle = styler.StyleAt(tempPos);
+ if (!IsCommentStyle(tempStyle)
+ && tempStyle != SCE_SQL_DEFAULT) {
+ isAllClear = false;
+ break;
+ }
+ }
+ if (isAllClear) {
+ startPos = lastNLPos + 1;
+ break;
+ }
+ }
+ }
+ lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
}
+ // And because folding ends at ';', keep going until we find one
+ // Otherwise if create ... view ... as is split over multiple
+ // lines the folding won't always update immediately.
+ unsigned int docLength = styler.Length();
+ for (; endPos < docLength; ++endPos) {
+ if (styler.SafeGetCharAt(endPos) == ';') {
+ break;
+ }
+ }
+
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
@@ -576,7 +653,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
// this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
// eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
bool statementFound = false;
- unsigned short int sqlStatesCurrentLine = 0;
+ sql_state_t sqlStatesCurrentLine = 0;
if (!options.foldOnlyBegin) {
sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
}
@@ -606,6 +683,16 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
}
if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine))
sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false);
+ if (sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {
+ if (sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine)) {
+ if (sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {
+ levelNext--;
+ sqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, false);
+ }
+ sqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, false);
+ }
+ sqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, false);
+ }
}
if (ch == ':' && chNext == '=' && !IsCommentStyle(style))
sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
@@ -805,6 +892,19 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
levelNext++;
statementFound = true;
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "create") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "view") == 0 &&
+ sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "as") == 0 &&
+ sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine) &&
+ ! sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, true);
+ levelNext++;
}
}
if (atEOL) {