File indexing completed on 2024-04-21 04:36:04

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 <QString>
0021 #include <QChar>
0022 
0023 namespace Utils {
0024 enum { T_ACCESS, T_PAREN, T_BRACKET, T_IDE, T_UNKNOWN, T_TEMP };
0025 
0026 int expressionAt(const QString& text, int index)
0027 {
0028     if (index == 0) {
0029         return 0;
0030     }
0031 
0032     int last = T_UNKNOWN;
0033     int start = index;
0034     --index;
0035 
0036     while (index > 0) {
0037         while (index > 0 && text[index].isSpace()) {
0038             --index;
0039         }
0040 
0041         QChar ch = text[index];
0042         QString ch2 = text.mid(index - 1, 2);
0043         if ((last != T_IDE) && (ch.isLetterOrNumber() || ch == '_' || ch == '$')) {
0044             while (index > 0 && (text[index].isLetterOrNumber() || text[index] == '_' || text[index] == '$')) {
0045                 --index;
0046             }
0047             last = T_IDE;
0048         } else if (last != T_IDE && ch == ')') {
0049             int count = 0;
0050             while (index > 0) {
0051                 QChar ch = text[index];
0052                 if (ch == '(') {
0053                     ++count;
0054                 } else if (ch == ')') {
0055                     --count;
0056                 }
0057                 --index;
0058                 if (count == 0) {
0059                     //index;
0060                     last = T_PAREN;
0061                     break;
0062                 }
0063             }
0064         } else if (ch == ']') {
0065             int count = 0;
0066             while (index > 0) {
0067                 QChar ch = text[index];
0068                 if (ch == '[') {
0069                     ++count;
0070                 } else if (ch == ']') {
0071                     --count;
0072                 } else if (count == 0) {
0073                     //--index;
0074                     last = T_BRACKET;
0075                     break;
0076                 }
0077                 --index;
0078             }
0079         } else if (ch2 == "::") {
0080             index -= 2;
0081             last = T_ACCESS;
0082         } else if (ch2 == "->") {
0083             index -= 2;
0084             last = T_ACCESS;
0085         } else {
0086             if (start > index) {
0087                 ++index;
0088             }
0089             last = T_UNKNOWN;
0090             break;
0091         }
0092     }
0093 
0094     ///If we're at the first item, the above algorithm cannot be used safely,
0095     ///so just determine whether the sign is valid for the beginning of an expression, if it isn't reject it.
0096     if (index == 0 && start > index && !(text[index].isLetterOrNumber() || text[index] == '_' || text[index] == '$' || text[index] == ':')) {
0097         ++index;
0098     }
0099 
0100     return index;
0101 }
0102 }