File indexing completed on 2021-12-21 13:15:51

0001 /*
0002    Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License version 2 as published by the Free Software Foundation.
0007 
0008    This library is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    Library General Public License for more details.
0012 
0013    You should have received a copy of the GNU Library General Public License
0014    along with this library; see the file COPYING.LIB.  If not, write to
0015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0016    Boston, MA 02110-1301, USA.
0017  */
0018 
0019 #include <language/duchain/stringhelpers.h>
0020 #include <language/duchain/safetycounter.h>
0021 #include <QString>
0022 #include <QChar>
0023 
0024 namespace Utils {
0025 enum { T_ACCESS, T_PAREN, T_BRACKET, T_IDE, T_UNKNOWN, T_TEMP };
0026 
0027 int expressionAt(const QString& text, int index)
0028 {
0029     if (index == 0) {
0030         return 0;
0031     }
0032 
0033     int last = T_UNKNOWN;
0034     int start = index;
0035     --index;
0036 
0037     while (index > 0) {
0038         while (index > 0 && text[index].isSpace()) {
0039             --index;
0040         }
0041 
0042         QChar ch = text[index];
0043         QString ch2 = text.mid(index - 1, 2);
0044         if ((last != T_IDE) && (ch.isLetterOrNumber() || ch == '_' || ch == '$')) {
0045             while (index > 0 && (text[index].isLetterOrNumber() || text[index] == '_' || text[index] == '$')) {
0046                 --index;
0047             }
0048             last = T_IDE;
0049         } else if (last != T_IDE && ch == ')') {
0050             int count = 0;
0051             while (index > 0) {
0052                 QChar ch = text[index];
0053                 if (ch == '(') {
0054                     ++count;
0055                 } else if (ch == ')') {
0056                     --count;
0057                 }
0058                 --index;
0059                 if (count == 0) {
0060                     //index;
0061                     last = T_PAREN;
0062                     break;
0063                 }
0064             }
0065         } else if (ch == ']') {
0066             int count = 0;
0067             while (index > 0) {
0068                 QChar ch = text[index];
0069                 if (ch == '[') {
0070                     ++count;
0071                 } else if (ch == ']') {
0072                     --count;
0073                 } else if (count == 0) {
0074                     //--index;
0075                     last = T_BRACKET;
0076                     break;
0077                 }
0078                 --index;
0079             }
0080         } else if (ch2 == "::") {
0081             index -= 2;
0082             last = T_ACCESS;
0083         } else if (ch2 == "->") {
0084             index -= 2;
0085             last = T_ACCESS;
0086         } else {
0087             if (start > index) {
0088                 ++index;
0089             }
0090             last = T_UNKNOWN;
0091             break;
0092         }
0093     }
0094 
0095     ///If we're at the first item, the above algorithm cannot be used safely,
0096     ///so just determine whether the sign is valid for the beginning of an expression, if it isn't reject it.
0097     if (index == 0 && start > index && !(text[index].isLetterOrNumber() || text[index] == '_' || text[index] == '$' || text[index] == ':')) {
0098         ++index;
0099     }
0100 
0101     return index;
0102 }
0103 }