@Override
  public void execute(SensorContext context) {
    List<TreeVisitor> treeVisitors = Lists.newArrayList();
    boolean isAtLeastSq62 = context.getSonarQubeVersion().isGreaterThanOrEqual(V6_2);

    MetricsVisitor metricsVisitor =
        new MetricsVisitor(
            context,
            noSonarFilter,
            context.settings().getBoolean(JavaScriptPlugin.IGNORE_HEADER_COMMENTS),
            fileLinesContextFactory,
            isAtLeastSq62);

    treeVisitors.add(metricsVisitor);
    treeVisitors.add(new HighlighterVisitor(context, fileSystem));
    treeVisitors.add(new SeChecksDispatcher(checks.seChecks()));
    treeVisitors.add(new CpdVisitor(fileSystem, context));
    treeVisitors.addAll(checks.visitorChecks());

    for (TreeVisitor check : treeVisitors) {
      if (check instanceof ParsingErrorCheck) {
        parsingErrorRuleKey = checks.ruleKeyFor((JavaScriptCheck) check);
        break;
      }
    }

    ProgressReport progressReport =
        new ProgressReport(
            "Report about progress of Javascript analyzer", TimeUnit.SECONDS.toMillis(10));
    progressReport.start(Lists.newArrayList(fileSystem.files(mainFilePredicate)));

    analyseFiles(context, treeVisitors, fileSystem.inputFiles(mainFilePredicate), progressReport);

    executeCoverageSensors(context, metricsVisitor.linesOfCode(), isAtLeastSq62);
  }
 private static void stopProgressReport(ProgressReport progressReport, boolean success) {
   if (success) {
     progressReport.stop();
   } else {
     progressReport.cancel();
   }
 }
  /**
   * Used to do scan of test files.
   *
   * @param files
   */
  public void simpleScan(Iterable<File> files) {
    SourceProject project = (SourceProject) index.search("Java Project");
    VisitorContext context = new VisitorContext(project);
    visitor.setContext(context);

    ProgressReport progressReport =
        new ProgressReport(
            "Report about progress of Java AST analyzer", TimeUnit.SECONDS.toMillis(10));
    progressReport.start(Lists.newArrayList(files));

    boolean successfulyCompleted = false;
    try {
      for (File file : files) {
        simpleScan(file, context);
        progressReport.nextFile();
      }
      successfulyCompleted = true;
    } finally {
      if (successfulyCompleted) {
        progressReport.stop();
      } else {
        progressReport.cancel();
      }
    }
  }
 @VisibleForTesting
 protected void analyseFiles(
     SensorContext context,
     List<TreeVisitor> treeVisitors,
     Iterable<InputFile> inputFiles,
     ProgressReport progressReport) {
   boolean success = false;
   try {
     for (InputFile inputFile : inputFiles) {
       // check for cancellation of the analysis (by SonarQube or SonarLint). See SONARJS-761.
       if (context.getSonarQubeVersion().isGreaterThanOrEqual(V6_0) && context.isCancelled()) {
         throw new CancellationException(
             "Analysis interrupted because the SensorContext is in cancelled state");
       }
       if (!isExcluded(inputFile.file())) {
         analyse(context, inputFile, treeVisitors);
       }
       progressReport.nextFile();
     }
     success = true;
   } catch (CancellationException e) {
     // do not propagate the exception
     LOG.debug(e.toString());
   } finally {
     stopProgressReport(progressReport, success);
   }
 }