SimpleLexer.cpp 4.69 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
**
10
** GNU Lesser General Public License Usage
11
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
con's avatar
con committed
30
**
31
**************************************************************************/
con's avatar
con committed
32
33

#include "SimpleLexer.h"
hjk's avatar
hjk committed
34

Tobias Hunger's avatar
Tobias Hunger committed
35
36
#include "ObjectiveCTypeQualifiers.h"

con's avatar
con committed
37
38
39
40
41
42
43
44
45
#include <Lexer.h>
#include <Token.h>
#include <QtDebug>

using namespace CPlusPlus;

SimpleLexer::SimpleLexer()
    : _lastState(0),
      _skipComments(false),
46
      _qtMocRunEnabled(true),
47
      _objCEnabled(false),
Leandro Melo's avatar
Leandro Melo committed
48
49
      _endedJoined(false),
      _cxx0xEnabled(false)
Roberto Raggi's avatar
Roberto Raggi committed
50
51
{
}
con's avatar
con committed
52
53
54
55
56

SimpleLexer::~SimpleLexer()
{ }

bool SimpleLexer::qtMocRunEnabled() const
hjk's avatar
hjk committed
57
58
59
{
    return _qtMocRunEnabled;
}
con's avatar
con committed
60
61

void SimpleLexer::setQtMocRunEnabled(bool enabled)
hjk's avatar
hjk committed
62
63
64
{
    _qtMocRunEnabled = enabled;
}
con's avatar
con committed
65

Roberto Raggi's avatar
Roberto Raggi committed
66
bool SimpleLexer::objCEnabled() const
67
{
Roberto Raggi's avatar
Roberto Raggi committed
68
    return _objCEnabled;
69
70
}

Roberto Raggi's avatar
Roberto Raggi committed
71
void SimpleLexer::setObjCEnabled(bool onoff)
72
{
Roberto Raggi's avatar
Roberto Raggi committed
73
    _objCEnabled = onoff;
74
75
}

76
77
78
79
80
81
82
83
84
85
bool SimpleLexer::cxx0xEnabled() const
{
    return _cxx0xEnabled;
}

void SimpleLexer::setCxx0xEnabled(bool enabled)
{
    _cxx0xEnabled = enabled;
}

con's avatar
con committed
86
bool SimpleLexer::skipComments() const
hjk's avatar
hjk committed
87
88
89
{
    return _skipComments;
}
con's avatar
con committed
90
91

void SimpleLexer::setSkipComments(bool skipComments)
hjk's avatar
hjk committed
92
93
94
{
    _skipComments = skipComments;
}
con's avatar
con committed
95

96
97
98
99
100
bool SimpleLexer::endedJoined() const
{
    return _endedJoined;
}

Erik Verbruggen's avatar
Erik Verbruggen committed
101
QList<Token> SimpleLexer::operator()(const QString &text, int state)
con's avatar
con committed
102
{
Erik Verbruggen's avatar
Erik Verbruggen committed
103
    QList<Token> tokens;
con's avatar
con committed
104
105
106
107
108
109
110

    const QByteArray bytes = text.toLatin1();
    const char *firstChar = bytes.constData();
    const char *lastChar = firstChar + bytes.size();

    Lexer lex(firstChar, lastChar);
    lex.setQtMocRunEnabled(_qtMocRunEnabled);
Roberto Raggi's avatar
Roberto Raggi committed
111
    lex.setObjCEnabled(_objCEnabled);
112
    lex.setStartWithNewline(true);
Erik Verbruggen's avatar
Erik Verbruggen committed
113
    lex.setObjCEnabled(_objCEnabled);
114
    lex.setCxxOxEnabled(_cxx0xEnabled);
con's avatar
con committed
115
116
117
118
119
120
121
122
123
124
125
126

    if (! _skipComments)
        lex.setScanCommentTokens(true);

    if (state != -1)
        lex.setState(state & 0xff);

    bool inPreproc = false;

    for (;;) {
        Token tk;
        lex(&tk);
127
128
        if (tk.is(T_EOF_SYMBOL)) {
            _endedJoined = tk.joined();
con's avatar
con committed
129
            break;
130
        }
con's avatar
con committed
131

132
        QStringRef spell = text.midRef(lex.tokenOffset(), lex.tokenLength());
con's avatar
con committed
133
134
        lex.setScanAngleStringLiteralTokens(false);

135
        if (tk.f.newline && tk.is(T_POUND))
con's avatar
con committed
136
            inPreproc = true;
Erik Verbruggen's avatar
Erik Verbruggen committed
137
        else if (inPreproc && tokens.size() == 1 && tk.is(T_IDENTIFIER) &&
138
                 spell == QLatin1String("include"))
con's avatar
con committed
139
            lex.setScanAngleStringLiteralTokens(true);
140
        else if (_objCEnabled
Erik Verbruggen's avatar
Erik Verbruggen committed
141
                 && inPreproc && tokens.size() == 1 && tk.is(T_IDENTIFIER) &&
142
                 spell == QLatin1String("import"))
143
            lex.setScanAngleStringLiteralTokens(true);
con's avatar
con committed
144

Erik Verbruggen's avatar
Erik Verbruggen committed
145
        tokens.append(tk);
con's avatar
con committed
146
147
148
149
150
151
    }

    _lastState = lex.state();
    return tokens;
}

Erik Verbruggen's avatar
Erik Verbruggen committed
152
int SimpleLexer::tokenAt(const QList<Token> &tokens, unsigned offset)
Erik Verbruggen's avatar
Erik Verbruggen committed
153
154
{
    for (int index = tokens.size() - 1; index >= 0; --index) {
Erik Verbruggen's avatar
Erik Verbruggen committed
155
156
        const Token &tk = tokens.at(index);
        if (tk.begin() <= offset && tk.end() >= offset)
Erik Verbruggen's avatar
Erik Verbruggen committed
157
158
159
160
161
            return index;
    }

    return -1;
}
con's avatar
con committed
162

Erik Verbruggen's avatar
Erik Verbruggen committed
163
164
165
166
Token SimpleLexer::tokenAt(const QString &text,
                           unsigned offset,
                           int state,
                           bool qtMocRunEnabled)
Erik Verbruggen's avatar
Erik Verbruggen committed
167
168
169
{
    SimpleLexer tokenize;
    tokenize.setQtMocRunEnabled(qtMocRunEnabled);
Erik Verbruggen's avatar
Erik Verbruggen committed
170
    const QList<Token> tokens = tokenize(text, state);
Erik Verbruggen's avatar
Erik Verbruggen committed
171
    const int tokenIdx = tokenAt(tokens, offset);
Erik Verbruggen's avatar
Erik Verbruggen committed
172
    return (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
Erik Verbruggen's avatar
Erik Verbruggen committed
173
174
}

Erik Verbruggen's avatar
Erik Verbruggen committed
175
int SimpleLexer::tokenBefore(const QList<Token> &tokens, unsigned offset)
Erik Verbruggen's avatar
Erik Verbruggen committed
176
177
{
    for (int index = tokens.size() - 1; index >= 0; --index) {
Erik Verbruggen's avatar
Erik Verbruggen committed
178
        const Token &tk = tokens.at(index);
Erik Verbruggen's avatar
Erik Verbruggen committed
179
        if (tk.begin() <= offset)
Erik Verbruggen's avatar
Erik Verbruggen committed
180
181
182
183
184
            return index;
    }

    return -1;
}