File indexing completed on 2024-04-21 04:34:33

0001 /*
0002  * This file is part of KDevelop Krazy2 Plugin.
0003  *
0004  * Copyright 2012 Daniel Calviño Sánchez <danxuliu@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License
0008  * as published by the Free Software Foundation; either version 2
0009  * of the License, or (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License
0017  * along with this program. If not, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "analysisresultsparser.h"
0021 
0022 #include <QRegExp>
0023 
0024 #include "analysisresults.h"
0025 #include "checker.h"
0026 #include "issue.h"
0027 
0028 //public:
0029 
0030 AnalysisResultsParser::AnalysisResultsParser():
0031     m_analysisResults(nullptr),
0032     m_checker(nullptr),
0033     m_checkerBeingInitialized(nullptr) {
0034 }
0035 
0036 void AnalysisResultsParser::setAnalysisResults(AnalysisResults* analysisResults) {
0037     m_analysisResults = analysisResults;
0038 }
0039 
0040 void AnalysisResultsParser::parse(const QByteArray& data) {
0041     m_xmlStreamReader.addData(data);
0042 
0043     while (!m_xmlStreamReader.atEnd()) {
0044         m_xmlStreamReader.readNext();
0045 
0046         if (isStartElement("file-type")) {
0047             processFileTypeStart();
0048         }
0049         if (isStartElement("check")) {
0050             processCheckStart();
0051         }
0052         if (isEndElement("explanation")) {
0053             processExplanationEnd();
0054         }
0055         if (isStartElement("file")) {
0056             processFileStart();
0057         }
0058         if (isEndElement("file")) {
0059             processFileEnd();
0060         }
0061         if (isEndElement("message")) {
0062             processMessageEnd();
0063         }
0064         if (isStartElement("line")) {
0065             processLineStart();
0066         }
0067         if (isEndElement("line")) {
0068             processLineEnd();
0069         }
0070         if (m_xmlStreamReader.isCharacters()) {
0071             m_text = m_xmlStreamReader.text().toString().trimmed();
0072         }
0073     }
0074 }
0075 
0076 //private:
0077 
0078 bool AnalysisResultsParser::isStartElement(const QString& elementName) {
0079     return m_xmlStreamReader.isStartElement() &&
0080            m_xmlStreamReader.name() == elementName;
0081 }
0082 
0083 bool AnalysisResultsParser::isEndElement(const QString& elementName) {
0084     return m_xmlStreamReader.isEndElement() &&
0085            m_xmlStreamReader.name() == elementName;
0086 }
0087 
0088 void AnalysisResultsParser::processFileTypeStart() {
0089     m_checkerFileType = m_xmlStreamReader.attributes().value("value").toString();
0090 }
0091 
0092 void AnalysisResultsParser::processCheckStart() {
0093     QRegExp regExp("(.*) \\[(.*)\\]\\.\\.\\.");
0094     regExp.indexIn(m_xmlStreamReader.attributes().value("desc").toString());
0095     QString checkerDescription = regExp.cap(1);
0096     QString checkerName = regExp.cap(2);
0097 
0098     if (checkerDescription == "no description available") {
0099         checkerDescription = "";
0100     }
0101 
0102     m_checker = m_analysisResults->findChecker(m_checkerFileType, checkerName);
0103     m_checkerBeingInitialized = nullptr;
0104 
0105     if (!m_checker) {
0106         m_checkerBeingInitialized = new Checker();
0107         m_checkerBeingInitialized->setName(checkerName);
0108         m_checkerBeingInitialized->setDescription(checkerDescription);
0109         m_checkerBeingInitialized->setFileType(m_checkerFileType);
0110 
0111         m_analysisResults->addChecker(m_checkerBeingInitialized);
0112 
0113         m_checker = m_checkerBeingInitialized;
0114     }
0115 }
0116 
0117 void AnalysisResultsParser::processExplanationEnd() {
0118     if (m_checkerBeingInitialized && m_text != "(no explanation available)") {
0119         m_checkerBeingInitialized->setExplanation(m_text);
0120     }
0121 }
0122 
0123 void AnalysisResultsParser::processFileStart() {
0124     m_issueFileName = m_xmlStreamReader.attributes().value("name").toString();
0125 }
0126 
0127 void AnalysisResultsParser::processFileEnd() {
0128     m_issueMessage.clear();
0129 }
0130 
0131 void AnalysisResultsParser::processMessageEnd() {
0132     m_issueMessage = m_text;
0133 }
0134 
0135 void AnalysisResultsParser::processLineStart() {
0136     if (!m_xmlStreamReader.attributes().hasAttribute("issue")) {
0137         return;
0138     }
0139 
0140     QString details = m_xmlStreamReader.attributes().value("issue").toString();
0141 
0142     QRegExp bracketsRegExp("\\[(.*)\\]");
0143     if (bracketsRegExp.indexIn(details) != -1) {
0144         details = bracketsRegExp.cap(1);
0145     }
0146 
0147     m_issueDetails = details;
0148 }
0149 
0150 void AnalysisResultsParser::processLineEnd() {
0151     QString message = m_issueMessage;
0152     if (!m_issueDetails.isEmpty()) {
0153         message = m_issueDetails;
0154         m_issueDetails.clear();
0155     }
0156 
0157     auto  issue = new Issue();
0158     issue->setChecker(m_checker);
0159     issue->setFileName(m_issueFileName);
0160     issue->setMessage(message);
0161     issue->setLine(m_text.toInt());
0162 
0163     m_analysisResults->addIssue(issue);
0164 }