source: trunk/tools/porting/src/tokenengine.cpp@ 315

Last change on this file since 315 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the qt3to4 porting application of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "tokenengine.h"
43
44QT_BEGIN_NAMESPACE
45
46namespace TokenEngine {
47
48/*
49 Add a container-global attribute.
50*/
51void TokenAttributes::addAttribute(const QByteArray &name, const QByteArray &value)
52{
53 const QByteArray keyText = makeKeyText(-1, name);
54 attributes.insert(keyText, value);
55}
56
57/*
58 Retrieve container-global attribute.
59*/
60QByteArray TokenAttributes::attribute(const QByteArray &name) const
61{
62 const QByteArray keyText = makeKeyText(-1, name);
63 return attributes.value(keyText);
64}
65
66/*
67 Add an attribute. Note: Don't use names starting with a number, that will
68 break the indexing.
69*/
70void TokenAttributes::addAttribute(const int index, const QByteArray &name, const QByteArray &value)
71{
72 const QByteArray keyText = makeKeyText(index, name);
73 attributes.insert(keyText, value);
74}
75
76QByteArray TokenAttributes::attribute(const int index, const QByteArray &name) const
77{
78 const QByteArray keyText = makeKeyText(index, name);
79 return attributes.value(keyText);
80}
81
82QByteArray TokenAttributes::makeKeyText(const int index, const QByteArray &name) const
83{
84 QByteArray indexText;
85 return indexText.setNum(index) + name;
86}
87
88
89/*
90 Construnct an empty TokenContainer.
91*/
92TokenContainer::TokenContainer()
93{
94 d = new TokenContainerData();
95 d->typeInfo = 0;
96}
97
98/*
99 Construnct a TokenContainer from data
100*/
101TokenContainer::TokenContainer(QByteArray text, QVector<Token> tokens, TypeInfo *typeInfo)
102{
103 d = new TokenContainerData();
104 d->text = text;
105 d->tokens = tokens;
106 if(typeInfo == 0)
107 d->typeInfo = new TypeInfo();
108 else
109 d->typeInfo = typeInfo;
110}
111
112int TokenContainer::count() const
113{
114 return d->tokens.count();
115}
116
117QByteArray TokenContainer::text(const int index) const
118{
119 Token token = d->tokens.at(index);
120 return d->text.mid(token.start, token.length);
121}
122
123QByteArray TokenContainer::tempText(const int index) const
124{
125 Token token = d->tokens.at(index);
126 return QByteArray::fromRawData(d->text.constData() + token.start, token.length);
127}
128
129QByteArray TokenContainer::fullText() const
130{
131 return d->text;
132}
133
134TokenContainer TokenContainer::tokenContainer(const int index) const
135{
136 Q_UNUSED(index);
137 return *this;
138}
139
140Token TokenContainer::token(const int index) const
141{
142 return d->tokens.at(index);
143}
144
145TypeInfo *TokenContainer::typeInfo()
146{
147 return d->typeInfo;
148}
149
150TokenAttributes *TokenContainer::tokenAttributes()
151{
152 return d->tokenAttributes;
153}
154
155const TokenAttributes *TokenContainer::tokenAttributes() const
156{
157 return d->tokenAttributes;
158}
159
160/*
161 Returns the line number for the given index.
162*/
163int TokenContainer::line(int index) const
164{
165 //This algorithm is a bit more complicated than it should be,
166 //since we have to search for newlines inside comments.
167 //(Comments are tokenized as one token)
168 QByteArray contents = fullText();
169 int pos=0;
170 int lines=0;
171 for(int t=0; t < index; ++t) {
172 int tokenLength = d->tokens.at(t).length;
173 if((tokenLength == 1) && (text(t) == "\n")) {
174 ++lines;
175 } else if(tokenLength > 2) {// 3 is the minimum size for a comment (// + newline)
176 int newpos = d->tokens.at(t).length;
177 for(int p = pos; p < newpos; ++p) {
178 if(contents[p] == '\n')
179 ++lines;
180 }
181 }
182 pos += d->tokens.at(t).length;
183 }
184 return lines;
185}
186
187/*
188 Returns the column number for the given index.
189*/
190int TokenContainer::column(int index) const
191{
192 //Scan backwards, find \n.
193 int chars = 0;
194 int t = index;
195 while (t>0) {
196 if((d->tokens.at(t).length == 1) && (text(t) == "\n"))
197 break;
198 chars += d->tokens.at(t).length;
199 --t;
200 }
201 return chars;
202}
203
204TokenTempRef TokenContainer::tokenTempRef(const int index) const
205{
206 Q_ASSERT(index < d->tokens.count());
207 const Token token = d->tokens.at(index);
208 return TokenTempRef(d->text.constData() + token.start, token.length);
209}
210
211QByteArray TokenSection::fullText() const
212{
213 QByteArray text;
214 for (int t = m_start; t < m_start + m_count; ++t) {
215 text += m_tokenContainer.text(t);
216 }
217 return text;
218}
219
220QByteArray TokenList::fullText() const
221{
222 QByteArray text;
223 for (int t = 0; t < m_tokenList.count(); ++t) {
224 text += m_tokenContainer.text(m_tokenList.at(t));
225 }
226 return text;
227}
228
229TokenSectionSequence::TokenSectionSequence(QVector<TokenSection> tokenSections)
230:m_tokenSections(tokenSections), m_count(0)
231{
232 for(int s = 0; s < m_tokenSections.count(); ++s) {
233 m_startIndexes.append(m_count);
234 m_count += m_tokenSections.at(s).count();
235 }
236}
237
238QByteArray TokenSectionSequence::fullText() const
239{
240 QByteArray text;
241 foreach(TokenSection section, m_tokenSections) {
242 text += section.fullText();
243 }
244 return text;
245}
246
247int TokenSectionSequence::count() const
248{
249 return m_count;
250}
251
252QVector<TokenSection> TokenSectionSequence::tokenSections() const
253{
254 return m_tokenSections;
255}
256
257QByteArray TokenSectionSequence::text(const int index) const
258{
259 const int sectionIndex = findSection(index);
260 const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
261 return m_tokenSections.at(sectionIndex).text(sectionInternalIndex);
262}
263
264QByteArray TokenSectionSequence::tempText(const int index) const
265{
266 const int sectionIndex = findSection(index);
267 const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
268 return m_tokenSections.at(sectionIndex).tempText(sectionInternalIndex);
269}
270
271
272TokenContainer TokenSectionSequence::tokenContainer(const int index) const
273{
274 const int sectionIndex = findSection(index);
275 const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
276 return m_tokenSections.at(sectionIndex).tokenContainer(sectionInternalIndex);
277}
278
279int TokenSectionSequence::containerIndex(const int index) const
280{
281 const int sectionIndex = findSection(index);
282 const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
283 return m_tokenSections.at(sectionIndex).containerIndex(sectionInternalIndex);
284}
285
286int TokenSectionSequence::findSection(const int index) const
287{
288 int c = 0;
289 bool found = false;
290 //Here we do a linear search through all collections in the list,
291 //which could turn out to be to slow.
292 while(!found && c < m_tokenSections.count()) {
293 const int sectionEnd = m_startIndexes.at(c)
294 + m_tokenSections.at(c).count();
295 if (index < sectionEnd)
296 found = true;
297 else
298 ++c;
299 }
300 if(!found) {
301 //error
302 Q_ASSERT(0);
303 return -1;
304 }
305 Q_ASSERT(c < m_tokenSections.count());
306 return c;
307}
308
309int TokenSectionSequence::calculateInternalIndex(const int index, const int sectionIndex) const
310{
311 const int sectionInternalIndex =
312 index - m_startIndexes.at(sectionIndex);
313 Q_ASSERT(sectionInternalIndex < m_tokenSections.at(sectionIndex).count());
314 return sectionInternalIndex;
315}
316
317
318TokenSectionSequenceIterator::TokenSectionSequenceIterator(const TokenSectionSequence &tokenSectionSequence)
319:m_currentSection(0)
320,m_currentToken(-1)
321,m_numSections(tokenSectionSequence.m_tokenSections.count())
322,m_tokenSectionSequence(tokenSectionSequence)
323
324{ }
325
326/*
327 Resets the token iterator.
328*/
329void TokenSectionSequenceIterator::reset()
330{
331 m_currentSection = 0;
332 m_currentToken = -1;
333}
334
335/*
336 Advances the token iterator.
337*/
338bool TokenSectionSequenceIterator::nextToken()
339{
340 if(m_tokenSectionSequence.m_tokenSections.isEmpty())
341 return false;
342 ++m_currentToken;
343 //check of we are past the end of the current section
344 if(m_currentToken < m_tokenSectionSequence.m_tokenSections.at(m_currentSection).count())
345 return true;
346 //Advance to the next non-empty section.
347 m_currentToken = 0;
348 do {
349 ++m_currentSection;
350 //return false if no more sections
351 if(m_currentSection >= m_numSections)
352 return false;
353 //skip empty sections
354 } while(m_tokenSectionSequence.m_tokenSections.at(m_currentSection).count() == 0);
355
356 return true;
357}
358
359/*
360 Returns the text for the current token;
361*/
362QByteArray TokenSectionSequenceIterator::text() const
363{
364 return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).text(m_currentToken);
365}
366
367/*
368 Returns the text for the current token as a temporary QByteArray;
369*/
370QByteArray TokenSectionSequenceIterator::tempText() const
371{
372 return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tempText(m_currentToken);
373}
374
375/*
376 Returns the container for the current token;
377*/
378TokenContainer TokenSectionSequenceIterator::tokenContainer() const
379{
380 return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tokenContainer(m_currentToken);
381}
382
383/*
384 Returns the containerIndex for the current token;
385*/
386int TokenSectionSequenceIterator::containerIndex() const
387{
388 return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).containerIndex(m_currentToken);
389}
390
391/*
392 Returns a temporary token reference for the current token for the current token;
393*/
394TokenTempRef TokenSectionSequenceIterator::tokenTempRef() const
395{
396 return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tokenTempRef(m_currentToken);
397}
398
399
400} //namespace TokenEngine
401
402QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.