src/scripttools/debugging/qscriptxmlparser.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtSCriptTools module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qscriptxmlparser_p.h"
       
    43 
       
    44 #include <QtCore/qstringlist.h>
       
    45 #include <QtCore/qxmlstream.h>
       
    46 #include <QtCore/qdebug.h>
       
    47 
       
    48 QT_BEGIN_NAMESPACE
       
    49 
       
    50 static void tokenUntil(QXmlStreamReader &reader, QXmlStreamReader::TokenType target,
       
    51                        QList<int> &lineNumbers)
       
    52 {
       
    53     int level = 0;
       
    54     while (!reader.atEnd()) {
       
    55         QXmlStreamReader::TokenType t = reader.readNext();
       
    56         if ((t == target) && (level == 0))
       
    57             return;
       
    58         if (t == QXmlStreamReader::StartElement) {
       
    59             ++level;
       
    60             QString line = reader.attributes().value(QLatin1String("line")).toString();
       
    61             if (!line.isEmpty())
       
    62                 lineNumbers.append(line.toInt());
       
    63         } else if (t == QXmlStreamReader::EndElement) {
       
    64             --level;
       
    65         }
       
    66     }
       
    67 //    Q_ASSERT_X(false, "QScriptXmlParser", "premature end of file");
       
    68 }
       
    69 
       
    70 QScriptXmlParser::Result QScriptXmlParser::parse(const QString &xml)
       
    71 {
       
    72     QMap<QString, int> functionsInfo;
       
    73     QList<int> lineNumbers;
       
    74     QXmlStreamReader reader(xml);
       
    75     reader.readNext(); // StartDocument
       
    76     reader.readNext(); // <program>
       
    77     reader.readNext(); // <source-elements>
       
    78     while (reader.readNext() == QXmlStreamReader::StartElement) {
       
    79 //        qDebug() << reader.name().toString();
       
    80         int line = reader.attributes().value(QLatin1String("line")).toString().toInt();
       
    81         lineNumbers.append(line);
       
    82         if (reader.name() == QLatin1String("function-declaration")) {
       
    83             // extract the line number, name and formal parameters
       
    84             reader.readNext(); // <name>
       
    85             reader.readNext(); // Characters
       
    86             QString name = reader.text().toString();
       
    87             reader.readNext(); // </name>
       
    88             reader.readNext(); // <formal-parameter-list>
       
    89             QStringList formalParameters;
       
    90             while (reader.readNext() == QXmlStreamReader::StartElement) {
       
    91                 reader.readNext(); // Characters
       
    92                 formalParameters.append(reader.text().toString());
       
    93                 reader.readNext(); // </identifier>
       
    94             }
       
    95             reader.readNext(); // <function-body>
       
    96             tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
    97 
       
    98             QString signature;
       
    99             signature.append(name);
       
   100             signature.append(QLatin1Char('('));
       
   101             for (int i = 0; i < formalParameters.size(); ++i) {
       
   102                 if (i > 0)
       
   103                     signature.append(QLatin1String(", "));
       
   104                 signature.append(formalParameters.at(i));
       
   105             }
       
   106             signature.append(QLatin1Char(')'));
       
   107             functionsInfo.insert(signature, line);
       
   108         } else if (reader.name() == QLatin1String("expression-statement")) {
       
   109             reader.readNext();
       
   110             if ((reader.name() == QLatin1String("binary-expression"))
       
   111                 && reader.attributes().value(QLatin1String("op")) == QLatin1String("=")) {
       
   112                 // try to match a statement of the form Foo.prototype.bar = function() { ... }
       
   113                 // this can be generalized...
       
   114                 QString first, second, third;
       
   115                 reader.readNext(); // LHS
       
   116                 if (reader.name() == QLatin1String("field-member-expression")) {
       
   117                     reader.readNext();
       
   118                     if (reader.name() == QLatin1String("field-member-expression")) {
       
   119                         reader.readNext();
       
   120                         if (reader.name() == QLatin1String("identifier")) {
       
   121                             reader.readNext();
       
   122                             first = reader.text().toString();
       
   123                         }
       
   124                         tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   125                         reader.readNext();
       
   126                         if (reader.name() == QLatin1String("identifier")) {
       
   127                             reader.readNext();
       
   128                             second = reader.text().toString();
       
   129                         }
       
   130                         tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   131                     } else if (reader.name() == QLatin1String("identifier")) {
       
   132                         reader.readNext();
       
   133                         first = reader.text().toString();
       
   134                     }
       
   135                     tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   136                     reader.readNext();
       
   137                     if (reader.name() == QLatin1String("identifier")) {
       
   138                         reader.readNext();
       
   139                         if (second.isEmpty())
       
   140                             second = reader.text().toString();
       
   141                         else
       
   142                             third = reader.text().toString();
       
   143                     }
       
   144                     tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   145                 }
       
   146                 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   147                 reader.readNext(); // RHS
       
   148                 if (reader.name() == QLatin1String("function-expression")) {
       
   149                     if (!first.isEmpty()) {
       
   150                         QString signature = first;
       
   151                         if (!second.isEmpty()) {
       
   152                             signature.append(QLatin1Char('.'));
       
   153                             signature.append(second);
       
   154                             if (!third.isEmpty()) {
       
   155                                 signature.append(QLatin1Char('.'));
       
   156                                 signature.append(third);
       
   157                             }
       
   158                         }
       
   159                         signature.append(QLatin1String("()"));
       
   160                         functionsInfo.insert(signature, line);
       
   161                     }
       
   162                 }
       
   163                 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   164             }
       
   165             tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   166         }
       
   167         tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
       
   168     }
       
   169     reader.readNext(); // </source-elements>
       
   170     reader.readNext(); // </program>
       
   171     reader.readNext(); // EndDocument
       
   172     Q_ASSERT(reader.atEnd());
       
   173     return Result(functionsInfo, lineNumbers.toSet());
       
   174 }
       
   175 
       
   176 QT_END_NAMESPACE