aboutsummaryrefslogtreecommitdiffhomepage
path: root/lexers/LexSQL.cxx
diff options
context:
space:
mode:
authorJerome LAFORGE <jerome.laforge@gmail.com>2012-03-13 09:56:10 +0100
committerJerome LAFORGE <jerome.laforge@gmail.com>2012-03-13 09:56:10 +0100
commit831c180bac4f0d9e1bc95adaee89726e48f20844 (patch)
tree24252944b25e6debb6533178ad5c7e229b97944d /lexers/LexSQL.cxx
parent595fc48ad6bc132e7b804d8e69afc4ab9e3dd59c (diff)
downloadscintilla-mirror-831c180bac4f0d9e1bc95adaee89726e48f20844.tar.gz
Improvement of folding for CASE/MERGE statement.
Bug #3503277.
Diffstat (limited to 'lexers/LexSQL.cxx')
-rw-r--r--lexers/LexSQL.cxx96
1 files changed, 72 insertions, 24 deletions
diff --git a/lexers/LexSQL.cxx b/lexers/LexSQL.cxx
index 2e3bc2bb8..dc4e164b4 100644
--- a/lexers/LexSQL.cxx
+++ b/lexers/LexSQL.cxx
@@ -1,8 +1,10 @@
+//-*- coding: utf-8 -*-
// Scintilla source code edit control
/** @file LexSQL.cxx
** Lexer for SQL, including PL/SQL and SQL*Plus.
+ ** Improved by Jérôme LAFORGE <jerome.laforge_AT_gmail_DOT_com> from 2010 to 2012.
**/
-// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2012 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
@@ -114,6 +116,24 @@ public :
return sqlStatesLine;
}
+ unsigned short int CaseMergeWithoutWhenFound (unsigned short int sqlStatesLine, bool found) {
+ if (found)
+ sqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
+ else
+ sqlStatesLine &= ~MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoSelectStatement (unsigned short int sqlStatesLine, bool found) {
+ if (found)
+ sqlStatesLine |= MASK_INTO_SELECT_STATEMENT;
+ else
+ sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT;
+
+ return sqlStatesLine;
+ }
+
unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
sqlStatesLine++;
@@ -144,6 +164,14 @@ public :
return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
}
+ bool IsIntoSelectStatement (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT) != 0;
+ }
+
+ bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
+ }
+
bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
}
@@ -165,12 +193,14 @@ public :
private :
std::vector <unsigned short int> sqlStatement;
enum {
+ MASK_NESTED_CASES = 0x01FF,
+ MASK_INTO_SELECT_STATEMENT = 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_MERGE_STATEMENT = 0x0800,
- MASK_NESTED_CASES = 0x07FF
+ MASK_IGNORE_WHEN = 0x8000
};
};
@@ -574,10 +604,17 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
endFound = false;
isUnfoldingIgnored = false;
}
- if ((!IsCommentStyle(style) && ch == ';') && sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) {
- // This is the end of "MERGE" statement.
- sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);
- levelNext-=2;
+ if ((!IsCommentStyle(style) && ch == ';')) {
+ if (sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) {
+ // This is the end of "MERGE" statement.
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--;
+ sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);
+ //sqlStatesCurrentLine = sqlStates.WhenThenFound(sqlStatesCurrentLine, false);
+ levelNext--;
+ }
+ if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine))
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, false);
}
if (options.foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
@@ -635,7 +672,10 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
s[j] = '\0';
}
- if (strcmp(s, "if") == 0) {
+ if (!options.foldOnlyBegin &&
+ strcmp(s, "select") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, true);
+ } else if (strcmp(s, "if") == 0) {
if (endFound) {
endFound = false;
if (options.foldOnlyBegin && !isUnfoldingIgnored) {
@@ -680,23 +720,21 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
}
if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
- levelNext--; //again for the "end case;" and block when
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--; //again for the "end case;" and block when
+ //sqlStatesCurrentLine = sqlStates.WhenThenFound(sqlStatesCurrentLine, false);
}
} else if (!options.foldOnlyBegin) {
- if (strcmp(s, "case") == 0) {
+ if (strcmp(s, "case") == 0)
sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
- //for case block increment 2 times
- if (!statementFound)
- levelNext++;
- }
-
- if (levelCurrent > levelNext) {
+ if (levelCurrent > levelNext)
levelCurrent = levelNext;
- }
+
if (!statementFound)
levelNext++;
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
statementFound = true;
} else if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
@@ -716,9 +754,13 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
// prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
statementFound = true;
- // we are in same case "} ELSE {" in C language
- levelCurrent--;
-
+ if (sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) && sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
+ levelNext++;
+ } else {
+ // we are in same case "} ELSE {" in C language
+ levelCurrent--;
+ }
} else if (strcmp(s, "begin") == 0) {
levelNext++;
sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
@@ -729,6 +771,8 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
(strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
+ if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE;
isUnfoldingIgnored = true;
@@ -746,8 +790,11 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
// Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
// and same way for MERGE statement.
if (!statementFound) {
- levelCurrent--;
- levelNext--;
+ if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
+ levelCurrent--;
+ levelNext--;
+ }
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
}
} else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
@@ -762,7 +809,8 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "merge") == 0) {
sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, true);
- levelNext += 2;
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
+ levelNext++;
statementFound = true;
}
}