|
16 | 16 | */ |
17 | 17 | package fr.cnes.sonar.plugins.icode.check; |
18 | 18 |
|
19 | | -import fr.cnes.icode.Analyzer; |
| 19 | +import com.google.common.collect.Lists; |
| 20 | +import com.google.common.collect.Maps; |
| 21 | +import fr.cnes.icode.data.AbstractChecker; |
20 | 22 | import fr.cnes.icode.data.CheckResult; |
21 | 23 | import fr.cnes.icode.exception.JFlexException; |
| 24 | +import fr.cnes.icode.logger.ICodeLogger; |
| 25 | +import fr.cnes.icode.services.checkers.CheckerContainer; |
| 26 | +import fr.cnes.icode.services.checkers.CheckerService; |
| 27 | +import fr.cnes.icode.services.languages.ILanguage; |
22 | 28 | import fr.cnes.icode.services.languages.LanguageService; |
23 | 29 | import fr.cnes.sonar.plugins.icode.exceptions.ICodeException; |
24 | 30 | import fr.cnes.sonar.plugins.icode.languages.Fortran77Language; |
@@ -170,42 +176,140 @@ protected void executeExternalResultsImport(final SensorContext sensorContext) { |
170 | 176 | */ |
171 | 177 | private void executeEmbeddedICode(final SensorContext sensorContext) { |
172 | 178 | // Initialisation of tools for analysis. |
173 | | - final Analyzer analyzer = new Analyzer(); |
174 | 179 | final FileSystem fileSystem = sensorContext.fileSystem(); |
175 | 180 | final FilePredicates predicates = fileSystem.predicates(); |
176 | 181 | final ActiveRules activeRules = sensorContext.activeRules(); |
177 | 182 | final Iterable<InputFile> inputFiles = fileSystem.inputFiles(predicates.hasType(InputFile.Type.MAIN)); |
178 | 183 | final HashSet<File> files = new HashSet<>(); |
179 | 184 | final HashMap<String,InputFile> filesMap = new HashMap<>(); |
180 | 185 |
|
181 | | - try { |
182 | | - // Gather all files in a Set. |
183 | | - for(final InputFile inputFile : inputFiles) { |
184 | | - files.add(inputFile.file()); |
185 | | - filesMap.put(inputFile.file().getPath(), inputFile); |
| 186 | + // Gather all files in a Set. |
| 187 | + for(final InputFile inputFile : inputFiles) { |
| 188 | + files.add(inputFile.file()); |
| 189 | + filesMap.put(inputFile.file().getPath(), inputFile); |
| 190 | + } |
| 191 | + |
| 192 | + // Run all checkers on all files. |
| 193 | + final List<CheckResult> results = sonarCheck(files, LanguageService.getLanguagesIds(), null); |
| 194 | + |
| 195 | + // Add each issue to SonarQube. |
| 196 | + for(final CheckResult result : results) { |
| 197 | + if(isRuleActive(activeRules, result.getName())) { // manage active rules |
| 198 | + saveIssue(sensorContext, result); |
| 199 | + } else if (ICodeMetricsProcessor.isMetric(result.getName())) { // manage trivial measures |
| 200 | + ICodeMetricsProcessor.saveMeasure(sensorContext, result); |
| 201 | + } else { // log ignored data |
| 202 | + LOGGER.info(String.format( |
| 203 | + "An issue for rule '%s' was detected by i-Code but this rule is deactivated in current analysis.", |
| 204 | + result.getName())); |
186 | 205 | } |
| 206 | + } |
| 207 | + |
| 208 | + ICodeMetricsProcessor.saveExtraMeasures(sensorContext, filesMap, results); |
| 209 | + |
| 210 | + } |
187 | 211 |
|
188 | | - // Run all checkers on all files. |
189 | | - final List<CheckResult> results = analyzer.stableCheck(files, LanguageService.getLanguagesIds(), null); |
190 | | - |
191 | | - // Add each issue to SonarQube. |
192 | | - for(final CheckResult result : results) { |
193 | | - if(isRuleActive(activeRules, result.getName())) { // manage active rules |
194 | | - saveIssue(sensorContext, result); |
195 | | - } else if (ICodeMetricsProcessor.isMetric(result.getName())) { // manage trivial measures |
196 | | - ICodeMetricsProcessor.saveMeasure(sensorContext, result); |
197 | | - } else { // log ignored data |
198 | | - LOGGER.info(String.format( |
199 | | - "An issue for rule '%s' was detected by i-Code but this rule is deactivated in current analysis.", |
200 | | - result.getName())); |
| 212 | + /** |
| 213 | + * <h1>{@link #sonarCheck(Set, List, List)}</h1> |
| 214 | + * <p> |
| 215 | + * This method apply all rules of the different contributions set in |
| 216 | + * parameter except the one excluded. File in parameters are being analyzed |
| 217 | + * by each contribution able to handle it or none if it isn't. |
| 218 | + * </p> |
| 219 | + * <p> |
| 220 | + * <strong>Important :</strong> Default configurations to run analysis are |
| 221 | + * available when setting parameters. |
| 222 | + * |
| 223 | + * @param pInputFiles |
| 224 | + * to analyze |
| 225 | + * @param pLanguageIds |
| 226 | + * to include in the analysis. <strong>Set null</strong> to run |
| 227 | + * an analysis including all contributions. |
| 228 | + * @param pExcludedCheckIds |
| 229 | + * rules identifier to exclude from the analysis. <strong>Set |
| 230 | + * null</strong> run analysis with every rules. |
| 231 | + * @return list of {@link CheckResult} found by the analysis. |
| 232 | + */ |
| 233 | + public List<CheckResult> sonarCheck(final Set<File> pInputFiles, final List<String> pLanguageIds, |
| 234 | + final List<String> pExcludedCheckIds) { |
| 235 | + final String methodName = "check"; |
| 236 | + ICodeLogger.entering(this.getClass().getName(), methodName); |
| 237 | + |
| 238 | + List<String> languageIds = pLanguageIds; |
| 239 | + if (languageIds == null) { |
| 240 | + languageIds = LanguageService.getLanguagesIds(); |
| 241 | + } |
| 242 | + List<String> excludedCheckIds = pExcludedCheckIds; |
| 243 | + if (pExcludedCheckIds == null) { |
| 244 | + excludedCheckIds = new ArrayList<>(); |
| 245 | + } |
| 246 | + final List<CheckResult> analysisResultCheckResult = new ArrayList<>(); |
| 247 | + |
| 248 | + // Contains checkers by language. |
| 249 | + final Map<String,List<CheckerContainer>> checkers = Maps.newHashMap(); |
| 250 | + // Contains files by language. |
| 251 | + final Map<String, List<File>> inputs = Maps.newLinkedHashMap(); |
| 252 | + // Get languages to check during the analysis. |
| 253 | + final List<ILanguage> languages = LanguageService.getLanguages(languageIds); |
| 254 | + // Get checkers to run during analysis. |
| 255 | + for(final ILanguage language : languages) { |
| 256 | + checkers.put(language.getId(), CheckerService.getCheckers(language.getId(), excludedCheckIds)); |
| 257 | + } |
| 258 | + |
| 259 | + // Sort files by language. |
| 260 | + for (final File file : pInputFiles) { |
| 261 | + final String languageId = LanguageService.getLanguageId(getFileExtension(file.getAbsolutePath())); |
| 262 | + final List<File> tempList = inputs.getOrDefault(languageId, Lists.newArrayList()); |
| 263 | + tempList.add(file); |
| 264 | + inputs.put(languageId, tempList); |
| 265 | + } |
| 266 | + // For each selected language, run selected checkers on selected files. |
| 267 | + for (final ILanguage language : languages) { |
| 268 | + for (final File input : inputs.getOrDefault(language.getId(), Lists.newArrayList())) { |
| 269 | + for (final CheckerContainer checker : checkers.get(language.getId())) { |
| 270 | + try { |
| 271 | + AbstractChecker check = checker.getChecker(); |
| 272 | + check.setInputFile(input); |
| 273 | + analysisResultCheckResult.addAll(check.run()); |
| 274 | + } catch (final Exception e) { |
| 275 | + // Set the error message. |
| 276 | + final String errorMessage = String.format("Internal i-Code error: exception [%s] thrown while checking [%s] on file [%s] - %s", |
| 277 | + e.getClass().getSimpleName(), checker.getName(), input.getPath(), e.getMessage()); |
| 278 | + // Log the error in i-Code and SonarQube logger. |
| 279 | + LOGGER.error(errorMessage, e); |
| 280 | + // Create an issue to be displayed in SonarQube. |
| 281 | + final CheckResult exception = new CheckResult("Parsing Error", "Parsing Error", input); |
| 282 | + exception.setLangageId(language.getId()); |
| 283 | + exception.setLocation("unknown"); |
| 284 | + exception.setLine(0); |
| 285 | + exception.setMessage(errorMessage); |
| 286 | + // Add the exception as a Parsing Error result. |
| 287 | + analysisResultCheckResult.add(exception); |
| 288 | + } |
201 | 289 | } |
202 | 290 | } |
| 291 | + } |
| 292 | + |
| 293 | + return analysisResultCheckResult; |
| 294 | + } |
| 295 | + |
| 296 | + /** |
| 297 | + * Return the file extension without the final point '.'. |
| 298 | + * |
| 299 | + * @param pFileName |
| 300 | + * to retrieve the extension |
| 301 | + * @return The extension name of the file |
| 302 | + */ |
| 303 | + private String getFileExtension(final String pFileName) { |
| 304 | + String extension = null; |
203 | 305 |
|
204 | | - ICodeMetricsProcessor.saveExtraMeasures(sensorContext, filesMap, results); |
| 306 | + final int i = pFileName.lastIndexOf('.'); |
| 307 | + final int p = Math.max(pFileName.lastIndexOf('/'), pFileName.lastIndexOf('\\')); |
205 | 308 |
|
206 | | - } catch (final JFlexException e) { |
207 | | - LOGGER.warn(e.getMessage(), e); |
| 309 | + if (i > p) { |
| 310 | + extension = pFileName.substring(i + 1); |
208 | 311 | } |
| 312 | + return extension; |
209 | 313 | } |
210 | 314 |
|
211 | 315 | /** |
|
0 commit comments