File indexing completed on 2024-04-21 04:34:32
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 #ifndef ANALYSISJOB_H 0021 #define ANALYSISJOB_H 0022 0023 #include <KJob> 0024 0025 #include <QProcess> 0026 0027 class AnalysisParameters; 0028 class AnalysisProgressParser; 0029 class AnalysisResults; 0030 class Checker; 0031 0032 /** 0033 * Job to analyze a directory with krazy2. 0034 * The job executes a krazy2 process asking it to analyze all the files 0035 * specified in the AnalysisParameters and then parses the output to populate an 0036 * AnalysisResults object. The checkers to run on the files are specified in the 0037 * AnalysisParameters too. The progress of the analysis is also notified. 0038 * 0039 * Several AnalysisParameters can be added to the job to be executed in the same 0040 * batch. That is, the AnalysisResults object will contain all the issues found 0041 * using each of the AnalysisParameters (although without duplicated issues) and 0042 * the progress report will take into account all the AnalysisParameters (the 0043 * progress will be proportional to the total number of checkers to be run), but 0044 * from the analysis perspective, each AnalysisParameters will be executed on 0045 * its own, like running several jobs each one with a single AnalysisParameters. 0046 * 0047 * The path to the krazy2 executable is got from "Krazy2" configuration group. 0048 * 0049 * The job is killable. 0050 */ 0051 class AnalysisJob: public KJob { 0052 Q_OBJECT 0053 public: 0054 0055 /** 0056 * Creates a new AnalysisJob with the given parent. 0057 * 0058 * @param parent The parent QObject. 0059 */ 0060 explicit AnalysisJob(QObject* parent = nullptr); 0061 0062 //<KJob> 0063 0064 /** 0065 * Starts the analysis. 0066 */ 0067 void start() override; 0068 0069 //</KJob> 0070 0071 /** 0072 * Adds analysis parameters. 0073 * The checkers have to have been initialized. 0074 * 0075 * The checkers from the list of available checkers will be copied to the 0076 * AnalysisResults object, so they must be fully initialized. The reason is 0077 * that krazy2 does not provide information in the results about whether a 0078 * checker is extra or not, so that information has to be got from the list 0079 * of available checkers. 0080 * 0081 * @param analysisParameters The analysis parameters to add. 0082 */ 0083 void addAnalysisParameters(const AnalysisParameters* analysisParameters); 0084 0085 /** 0086 * Sets the AnalysisResults to populate. 0087 * 0088 * @param analysisResults The AnalysisResults to populate. 0089 */ 0090 void setAnalysisResults(AnalysisResults* analysisResults); 0091 0092 protected: 0093 0094 //<KJob> 0095 0096 /** 0097 * Kills the underlying process. 0098 * 0099 * @return Always true. 0100 */ 0101 bool doKill() override; 0102 0103 //</KJob> 0104 0105 private: 0106 0107 /** 0108 * The list of AnalysisParameters. 0109 */ 0110 QList<const AnalysisParameters*> m_analysisParametersList; 0111 0112 /** 0113 * The analysis parameters to use for the current krazy2 execution. 0114 */ 0115 const AnalysisParameters* m_currentAnalysisParameters; 0116 0117 /** 0118 * A list of the lists with the names of the files to be analyzed. 0119 * They are just the names returned by each AnalysisParameters, stored to 0120 * avoid resolving the file names each time a new process is executed. 0121 */ 0122 QList<QStringList> m_namesOfFilesToBeAnalyzed; 0123 0124 /** 0125 * A list with the names of the files to be analyzed in the current krazy2 0126 * execution. 0127 */ 0128 QStringList m_currentNamesOfFilesToBeAnalyzed; 0129 0130 /** 0131 * The file types of the checkers to run of the current analysis parameters 0132 * that have not been run yet. 0133 * Only the checkers with a given file type are run each time. Thus, several 0134 * krazy2 executions may be needed to run all the checkers of the current 0135 * analysis parameters, and this list keeps track of the pending file types. 0136 * 0137 * @see checkersToRunAsKrazy2Arguments(QString) 0138 */ 0139 QStringList m_pendingFileTypes; 0140 0141 /** 0142 * The analysis results to populate. 0143 */ 0144 AnalysisResults* m_analysisResults; 0145 0146 /** 0147 * The KDevelop::IStatus to show the analysis progress. 0148 */ 0149 AnalysisProgressParser* m_analysisProgressParser; 0150 0151 /** 0152 * The krazy2 process to parse its output. 0153 */ 0154 QProcess* m_process; 0155 0156 /** 0157 * Returns the number of checkers that will be executed. 0158 * The executed checkers will depend on the types of the files analyzed and 0159 * the file types supported by each checker. 0160 * The returned number is just a hint. It will probably be the right number, 0161 * but it also may not. 0162 * 0163 * @param namesOfFilesToBeAnalyzed A list with file names. 0164 * @param checkersToRun The list of checkers to run on the given file names. 0165 * @return The number of checkers that will be executed. 0166 * @see isCheckerCompatibleWith(Checker*,QString) 0167 */ 0168 int calculateNumberOfCheckersToBeExecuted(const QStringList& namesOfFilesToBeAnalyzed, 0169 const QList<const Checker*>& checkersToRun) const; 0170 0171 /** 0172 * Returns whether the given checker can analyze any of the files with the 0173 * given names or not. 0174 * 0175 * @param checker The checker. 0176 * @param fileNames The names of the files. 0177 * @return True if the checker can analyze any file, false otherwise. 0178 * @see isCheckerCompatibleWith(Checker*,QString) 0179 */ 0180 bool isCheckerCompatibleWithAnyFile(const Checker* checker, 0181 const QStringList& fileNames) const; 0182 0183 /** 0184 * Returns whether the given checker can analyze the file with the given 0185 * name or not. 0186 * Being able to analyze the file or not depends on the file type of the 0187 * checker and the extension of the file. The file types and extensions 0188 * known by this method are based on Krazy2 lib/Krazy/Utils.pm fileType 0189 * function (commit d2301b9, 2012-05-26). Note, however, that future Krazy2 0190 * versions may support extensions not listed here. Thus, the value returned 0191 * by this method is just a hint. 0192 * 0193 * @param checker The checker. 0194 * @param fileName The name of the file. 0195 * @return True if the checker can analyze the file, false otherwise. 0196 */ 0197 bool isCheckerCompatibleWithFile(const Checker* checker, const QString& fileName) const; 0198 0199 /** 0200 * Sets the current analysis parameters (and names of files to be analyzed). 0201 * The list with the pending file types is populated with the file types of 0202 * the checkers of the now current analysis parameters. 0203 * 0204 * As a new set of analysis parameters is going to be used the number of 0205 * files for each file type assumed by the progress parser is reset too. 0206 */ 0207 void prepareNextAnalysisParameters(); 0208 0209 /** 0210 * Returns the list of checkers to run as a list of strings to be passed to 0211 * krazy2 as arguments. 0212 * The checkers to run are got from the current analysis parameters. The 0213 * list returned by AnalysisParameters contains both normal and extra 0214 * checkers. However, when telling krazy2 which checkers to run, normal 0215 * checkers and extra checkers must be passed in different arguments. 0216 * 0217 * Moreover, normal checkers and extra checkers can not be specified at the 0218 * same time; if "--check" argument is used, "--extra" argument takes no 0219 * effect. Thus, to execute extra checkers along with a subset of the normal 0220 * checkers, the "--exclude" argument has to be used to specify which normal 0221 * checkers should not be run (from all the available checkers), along with 0222 * an "--extra" argument to specify which extra checkers should be run. 0223 * 0224 * When the name of the checker is provided using "--check", "--extra" or 0225 * "--exclude" every checker with the given name is taken into account. For 0226 * example, as the spelling checker supports several file types, 0227 * "--checker spelling" would execute the spelling checker for c++, cmake, 0228 * desktop... To limit the file types of the checkers to run, "--types" 0229 * should be used. However, there is no way (that I am aware of) to run a 0230 * checker X for file type A and a checker Y for file type B but not a 0231 * checker X for file type B at the same time. Thus, only the checkers to 0232 * run for the given file type are executed at the same time. 0233 * 0234 * @param fileType The file type of the subgroup of checkers to run. 0235 * @return The krazy2 arguments as a list of strings. 0236 */ 0237 QStringList checkersToRunAsKrazy2Arguments(const QString& fileType) const; 0238 0239 /** 0240 * Starts the krazy2 process. 0241 * Only the checkers to run of the current analysis parameters and for the 0242 * given file type are executed. 0243 * 0244 * @param fileType The file type of the subgroup of checkers to run. 0245 */ 0246 void startAnalysis(const QString& fileType); 0247 0248 private Q_SLOTS: 0249 0250 /** 0251 * Updates the progress. 0252 */ 0253 void handleProcessReadyStandardError(); 0254 0255 /** 0256 * Adds the results for the current file type to the general results. 0257 * The next AnalysisParameters are prepared, if needed. Then, if there are 0258 * other file types pending, starts a new analysis for the next file type. 0259 * Else, ends this AnalysisJob emitting the result. 0260 * 0261 * @param exitCode Unused. 0262 */ 0263 void handleProcessFinished(int exitCode); 0264 0265 /** 0266 * Sets the error code and error text for this AnalysisJob and ends it 0267 * emitting the result. 0268 * 0269 * @param processError The error occurred in the underlying process. 0270 */ 0271 void handleProcessError(QProcess::ProcessError processError); 0272 0273 }; 0274 0275 #endif