sonar JavaScript plugin: any class extending CustomJavaScriptRulesDefinition will...
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 21 Aug 2016 04:17:50 +0000 (06:17 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 21 Aug 2016 04:17:50 +0000 (06:17 +0200)
So as in the Java plugin, I do not have to do anything :) Every time JavaScriptSquidSensor finds JavaScript code my rules will run.

Sonar/Plugins/sonar-custom-javascript-plugin/pom.xml
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/CustomPlugin.java
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/CustomRulesDefinition.java
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/CustomSensor.java [deleted file]
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/JavaScriptChecks.java [deleted file]
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/AverageLineLengthCalculator.java [deleted file]
Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/MinificationAssessor.java [deleted file]

index 3995d92..2b85884 100644 (file)
@@ -17,9 +17,9 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <sonar.apiVersion>5.6.1</sonar.apiVersion>
-    <javascript.plugin.version>2.14</javascript.plugin.version>
+    <javascript.plugin.version>2.15</javascript.plugin.version>
     <jdk.min.version>1.8</jdk.min.version>
-    <sonar.pluginKey>helloworld</sonar.pluginKey>
+    <sonar.pluginKey>customjavascriptplugin</sonar.pluginKey>
   </properties>
 
   <dependencies>
       <version>${sonar.apiVersion}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.sonarsource.java</groupId>
+      <artifactId>javascript-checks-testkit</artifactId>
+      <version>${javascript.plugin.version}</version>
+      <scope>test</scope>
+    </dependency>
        <dependency>
                <groupId>org.easytesting</groupId>
                <artifactId>fest-assert</artifactId>
index 641afa8..ef7f0d9 100644 (file)
@@ -10,7 +10,7 @@ public class CustomPlugin implements Plugin {
        public void define(Context context) {
            ImmutableList.Builder<Object> builder = ImmutableList.builder();
            builder.add(
-                       );
+                       CustomRulesDefinition.class);
            
            context.addExtensions(builder.build());
        }
index 4180004..5d98de2 100644 (file)
@@ -9,13 +9,11 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.server.debt.DebtRemediationFunction;
-import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
 import org.sonar.api.utils.AnnotationUtils;
-import org.sonar.check.Cardinality;
 import org.sonar.plugins.javascript.JavaScriptLanguage;
+import org.sonar.plugins.javascript.api.CustomJavaScriptRulesDefinition;
 import org.sonar.squidbridge.annotations.RuleTemplate;
-import org.sonar.squidbridge.rules.ExternalDescriptionLoader;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;
@@ -25,16 +23,46 @@ import com.google.gson.Gson;
 
 import de.example.custom.javascript.checks.CheckList;
 
-public class CustomRulesDefinition implements RulesDefinition {
+
+/**
+ * This class will be injected (SonarQube is using PicoContainer) in
+ * org.sonar.plugins.javascript.JavaScriptSquidSensor.
+ * 
+ * It seems like the SonarQube developers in charge of writing the JavaScript plugin tried to
+ * make easy the creation of custom Java plugins.
+ * 
+ * So, JavaScriptSquidSensor will be the object that will run my rules (my Checks) whenever it finds JavaScript code.
+ * I do not have to do anything else, what is great!
+ *
+ */
+public class CustomRulesDefinition extends CustomJavaScriptRulesDefinition {
        private static final String RESOURCE_BASE_PATH = "/de/example/l10n/javascript/rules/custom";
        
        private final Gson gson = new Gson();
        
+         @Override
+         public String repositoryName() {
+           return CheckList.REPOSITORY_NAME;
+         }
+
+         @Override
+         public String repositoryKey() {
+           return CheckList.REPOSITORY_KEY;
+         }
+
+         @Override
+         public Class[] checkClasses() {
+           return CheckList.getChecks().toArray();
+         }
+       
+         /**
+          * I do not want to use the define method implemented in org.sonar.plugins.javascript.api.CustomJavaScriptRulesDefinition.
+          */
        @Override
        public void define(Context context) {
                NewRepository repository = context
-                               .createRepository(CheckList.REPOSITORY_KEY, JavaScriptLanguage.KEY)
-                               .setName(CheckList.REPOSITORY_NAME);
+                               .createRepository(repositoryKey(), JavaScriptLanguage.KEY)
+                               .setName(repositoryName());
                List<Class> checks = CheckList.getChecks();
                new RulesDefinitionAnnotationLoader().load(repository, Iterables.toArray(checks, Class.class));
                for (Class ruleClass : checks) {
@@ -51,17 +79,16 @@ public class CustomRulesDefinition implements RulesDefinition {
       throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass);
     }
     String ruleKey = ruleAnnotation.key();
-    if (StringUtils.isEmpty(ruleKey)) {
+    if (StringUtils.isEmpty(ruleKey)) {        
       throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass);
     }
     NewRule rule = repository.rule(ruleKey);
     if (rule == null) {
       throw new IllegalStateException("No rule was created for " + ruleClass + " in " + repository.key());
     }
+    
+    // Check whether it is a Rule Template.
     rule.setTemplate(AnnotationUtils.getAnnotation(ruleClass, RuleTemplate.class) != null);
-    if (ruleAnnotation.cardinality() == Cardinality.MULTIPLE) {
-      throw new IllegalArgumentException("Cardinality is not supported, use the RuleTemplate annotation instead for " + ruleClass);
-    }
     ruleMetadata(ruleClass, rule);
   }
 
@@ -73,7 +100,7 @@ public class CustomRulesDefinition implements RulesDefinition {
   }
 
   private void addMetadata(NewRule rule, String metadataKey) {
-    URL resource = ExternalDescriptionLoader.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.json");
+    URL resource = CustomRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_javascript.json");
     if (resource != null) {
       RuleMetatada metatada = gson.fromJson(readResource(resource), RuleMetatada.class);
       rule.setSeverity(metatada.defaultSeverity.toUpperCase());
@@ -87,14 +114,14 @@ public class CustomRulesDefinition implements RulesDefinition {
     }
   }
 
-  private static void addHtmlDescription(NewRule rule, String metadataKey) {
-    URL resource = CustomRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.html");
+  private void addHtmlDescription(NewRule rule, String metadataKey) {
+    URL resource = CustomRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_javascript.html");
     if (resource != null) {
       rule.setHtmlDescription(readResource(resource));
     }
   }
 
-  private static String readResource(URL resource) {
+  private String readResource(URL resource) {
     try {
       return Resources.toString(resource, Charsets.UTF_8);
     } catch (IOException e) {
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/CustomSensor.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/CustomSensor.java
deleted file mode 100644 (file)
index e5285a5..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-package de.example.plugins.custom.javascript;
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-import java.io.File;
-import java.io.InterruptedIOException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputFile.Type;
-import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.rule.CheckFactory;
-import org.sonar.api.batch.sensor.Sensor;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.batch.sensor.issue.NewIssue;
-import org.sonar.api.batch.sensor.issue.NewIssueLocation;
-import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
-import org.sonar.api.config.Settings;
-import org.sonar.api.issue.NoSonarFilter;
-import org.sonar.api.measures.FileLinesContextFactory;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.javascript.checks.ParsingErrorCheck;
-import org.sonar.javascript.highlighter.HighlightSymbolTableBuilder;
-import org.sonar.javascript.parser.JavaScriptParserBuilder;
-import org.sonar.javascript.tree.visitors.CharsetAwareVisitor;
-import org.sonar.javascript.visitors.JavaScriptVisitorContext;
-import org.sonar.plugins.javascript.JavaScriptLanguage;
-import org.sonar.plugins.javascript.api.CustomJavaScriptRulesDefinition;
-import org.sonar.plugins.javascript.api.JavaScriptCheck;
-import org.sonar.plugins.javascript.api.tree.ScriptTree;
-import org.sonar.plugins.javascript.api.tree.Tree;
-import org.sonar.plugins.javascript.api.visitors.FileIssue;
-import org.sonar.plugins.javascript.api.visitors.Issue;
-import org.sonar.plugins.javascript.api.visitors.IssueLocation;
-import org.sonar.plugins.javascript.api.visitors.LineIssue;
-import org.sonar.plugins.javascript.api.visitors.PreciseIssue;
-import org.sonar.plugins.javascript.api.visitors.TreeVisitor;
-import org.sonar.plugins.javascript.api.visitors.TreeVisitorContext;
-import org.sonar.squidbridge.api.AnalysisException;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.sonar.sslr.api.RecognitionException;
-import com.sonar.sslr.api.typed.ActionParser;
-
-import de.example.custom.javascript.checks.CheckList;
-import de.example.plugins.custom.javascript.minify.MinificationAssessor;
-
-public class CustomSensor implements Sensor {
-
-  private static final Logger LOG = Loggers.get(CustomSensor.class);
-
-  private final JavaScriptChecks checks;
-  private final FileSystem fileSystem;
-  private final FilePredicate mainFilePredicate;
-  private final Settings settings;
-  private final ActionParser<Tree> parser;
-  // parsingErrorRuleKey equals null if ParsingErrorCheck is not activated
-  private RuleKey parsingErrorRuleKey = null;
-
-  public CustomSensor(
-    CheckFactory checkFactory, FileLinesContextFactory fileLinesContextFactory, FileSystem fileSystem, NoSonarFilter noSonarFilter, Settings settings) {
-    this(checkFactory, fileSystem, settings, null);
-  }
-
-  public CustomSensor(
-    CheckFactory checkFactory, FileSystem fileSystem,
-    Settings settings, @Nullable CustomJavaScriptRulesDefinition[] customRulesDefinition
-  ) {
-
-    this.checks = JavaScriptChecks.createJavaScriptCheck(checkFactory)
-      .addChecks(CheckList.REPOSITORY_KEY, CheckList.getChecks())
-      .addCustomChecks(customRulesDefinition);
-    this.fileSystem = fileSystem;
-    this.mainFilePredicate = fileSystem.predicates().and(
-      fileSystem.predicates().hasType(InputFile.Type.MAIN),
-      fileSystem.predicates().hasLanguage(JavaScriptLanguage.KEY));
-    this.settings = settings;
-    this.parser = JavaScriptParserBuilder.createParser(getEncoding());
-  }
-
-  @VisibleForTesting
-  protected void analyseFiles(SensorContext context, List<TreeVisitor> treeVisitors, Iterable<InputFile> inputFiles) {
-      for (InputFile inputFile : inputFiles) {
-        if (!isExcluded(inputFile.file())) {
-          analyse(context, inputFile, treeVisitors);
-        }
-      }
-  }
-  
-  private Charset getEncoding() {
-    return fileSystem.encoding();
-  }
-
-
-  private void analyse(SensorContext sensorContext, InputFile inputFile, List<TreeVisitor> visitors) {
-    ScriptTree scriptTree;
-
-    try {
-      scriptTree = (ScriptTree) parser.parse(new java.io.File(inputFile.absolutePath()));
-      scanFile(sensorContext, inputFile, visitors, scriptTree);
-
-    } catch (RecognitionException e) {
-      checkInterrupted(e);
-      LOG.error("Unable to parse file: " + inputFile.absolutePath());
-      LOG.error(e.getMessage());
-      processRecognitionException(e, sensorContext, inputFile);
-
-    } catch (Exception e) {
-      checkInterrupted(e);
-      throw new AnalysisException("Unable to analyse file: " + inputFile.absolutePath(), e);
-    }
-
-  }
-
-  private static void checkInterrupted(Exception e) {
-    Throwable cause = Throwables.getRootCause(e);
-    if (cause instanceof InterruptedException || cause instanceof InterruptedIOException) {
-      throw new AnalysisException("Analysis cancelled", e);
-    }
-  }
-
-  private void processRecognitionException(RecognitionException e, SensorContext sensorContext, InputFile inputFile) {
-    if (parsingErrorRuleKey != null) {
-      NewIssue newIssue = sensorContext.newIssue();
-
-      NewIssueLocation primaryLocation = newIssue.newLocation()
-        .message(e.getMessage())
-        .on(inputFile)
-        .at(inputFile.selectLine(e.getLine()));
-
-      newIssue
-        .forRule(parsingErrorRuleKey)
-        .at(primaryLocation)
-        .save();
-    }
-  }
-
-  private void scanFile(SensorContext sensorContext, InputFile inputFile, List<TreeVisitor> visitors, ScriptTree scriptTree) {
-    JavaScriptVisitorContext context = new JavaScriptVisitorContext(scriptTree, inputFile.file(), settings);
-
-    highlightSymbols(sensorContext.newSymbolTable().onFile(inputFile), context);
-
-    List<Issue> fileIssues = new ArrayList<>();
-
-    for (TreeVisitor visitor : visitors) {
-      if (visitor instanceof CharsetAwareVisitor) {
-        ((CharsetAwareVisitor) visitor).setCharset(fileSystem.encoding());
-      }
-
-      if (visitor instanceof JavaScriptCheck) {
-        fileIssues.addAll(((JavaScriptCheck) visitor).scanFile(context));
-
-      } else {
-        visitor.scanTree(context);
-      }
-
-    }
-
-    saveFileIssues(sensorContext, fileIssues, inputFile);
-  }
-
-
-  private static void highlightSymbols(NewSymbolTable newSymbolTable, TreeVisitorContext context) {
-    HighlightSymbolTableBuilder.build(newSymbolTable, context);
-  }
-
-  private void saveFileIssues(SensorContext sensorContext, List<Issue> fileIssues, InputFile inputFile) {
-    for (Issue issue : fileIssues) {
-      RuleKey ruleKey = ruleKey(issue.check());
-      if (issue instanceof FileIssue) {
-        saveFileIssue(sensorContext, inputFile, ruleKey, (FileIssue) issue);
-
-      } else if (issue instanceof LineIssue) {
-        saveLineIssue(sensorContext, inputFile, ruleKey, (LineIssue) issue);
-
-      } else {
-        savePreciseIssue(sensorContext, inputFile, ruleKey, (PreciseIssue)issue);
-      }
-    }
-  }
-
-  private static void savePreciseIssue(SensorContext sensorContext, InputFile inputFile, RuleKey ruleKey, PreciseIssue issue) {
-    NewIssue newIssue = sensorContext.newIssue();
-
-    newIssue
-      .forRule(ruleKey)
-      .at(newLocation(inputFile, newIssue, issue.primaryLocation()));
-
-    if (issue.cost() != null) {
-      newIssue.gap(issue.cost());
-    }
-
-    for (IssueLocation secondary : issue.secondaryLocations()) {
-      newIssue.addLocation(newLocation(inputFile, newIssue, secondary));
-    }
-    newIssue.save();
-  }
-
-
-  private static NewIssueLocation newLocation(InputFile inputFile, NewIssue issue, IssueLocation location) {
-    TextRange range = inputFile.newRange(
-      location.startLine(), location.startLineOffset(), location.endLine(), location.endLineOffset());
-
-    NewIssueLocation newLocation = issue.newLocation()
-      .on(inputFile)
-      .at(range);
-
-    if (location.message() != null) {
-      newLocation.message(location.message());
-    }
-    return newLocation;
-  }
-
-
-  private RuleKey ruleKey(JavaScriptCheck check) {
-    Preconditions.checkNotNull(check);
-    RuleKey ruleKey = checks.ruleKeyFor(check);
-    if (ruleKey == null) {
-      throw new IllegalStateException("No rule key found for a rule");
-    }
-    return ruleKey;
-  }
-
-  public boolean isExcluded(File file) {
-    boolean isMinified = new MinificationAssessor(getEncoding()).isMinified(file);
-    if (isMinified) {
-      LOG.debug("File [" + file.getAbsolutePath() + "] looks like a minified file and will not be analyzed");
-    }
-    return isMinified;
-  }
-
-  @Override
-  public void describe(SensorDescriptor descriptor) {
-    descriptor
-      .onlyOnLanguage(JavaScriptLanguage.KEY)
-      .name("Custom JavaScript Sensor")
-      .onlyOnFileType(Type.MAIN);
-  }
-
-  @Override
-  public void execute(SensorContext context) {
-    List<TreeVisitor> treeVisitors = Lists.newArrayList();
-    treeVisitors.addAll(checks.visitorChecks());
-
-    for (TreeVisitor check : treeVisitors) {
-      if (check instanceof ParsingErrorCheck) {
-        parsingErrorRuleKey = checks.ruleKeyFor((JavaScriptCheck) check);
-        break;
-      }
-    }
-
-    analyseFiles(context, treeVisitors, fileSystem.inputFiles(mainFilePredicate));
-
-  }
-
-
-  private static void saveLineIssue(SensorContext sensorContext, InputFile inputFile, RuleKey ruleKey, LineIssue issue) {
-    NewIssue newIssue = sensorContext.newIssue();
-
-    NewIssueLocation primaryLocation = newIssue.newLocation()
-      .message(issue.message())
-      .on(inputFile)
-      .at(inputFile.selectLine(issue.line()));
-
-    saveIssue(newIssue, primaryLocation, ruleKey, issue);
-  }
-
-  private static void saveFileIssue(SensorContext sensorContext, InputFile inputFile, RuleKey ruleKey, FileIssue issue) {
-    NewIssue newIssue = sensorContext.newIssue();
-
-    NewIssueLocation primaryLocation = newIssue.newLocation()
-      .message(issue.message())
-      .on(inputFile);
-
-    saveIssue(newIssue, primaryLocation, ruleKey, issue);
-  }
-
-  private static void saveIssue(NewIssue newIssue, NewIssueLocation primaryLocation, RuleKey ruleKey, Issue issue) {
-    newIssue
-      .forRule(ruleKey)
-      .at(primaryLocation);
-
-    if (issue.cost() != null) {
-      newIssue.gap(issue.cost());
-    }
-
-    newIssue.save();
-  }
-
-}
\ No newline at end of file
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/JavaScriptChecks.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/JavaScriptChecks.java
deleted file mode 100644 (file)
index c6af4e7..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package de.example.plugins.custom.javascript;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.rule.CheckFactory;
-import org.sonar.api.batch.rule.Checks;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.javascript.se.SeCheck;
-import org.sonar.plugins.javascript.api.CustomJavaScriptRulesDefinition;
-import org.sonar.plugins.javascript.api.JavaScriptCheck;
-import org.sonar.plugins.javascript.api.visitors.TreeVisitor;
-
-/**
- * Wrapper around Checks Object to ease the manipulation of the different JavaScript rule repositories.
- */
-public class JavaScriptChecks {
-
-  private final CheckFactory checkFactory;
-  private Set<Checks<JavaScriptCheck>> checksByRepository = Sets.newHashSet();
-
-  private JavaScriptChecks(CheckFactory checkFactory) {
-    this.checkFactory = checkFactory;
-  }
-
-  public static JavaScriptChecks createJavaScriptCheck(CheckFactory checkFactory) {
-    return new JavaScriptChecks(checkFactory);
-  }
-
-  public JavaScriptChecks addChecks(String repositoryKey, Iterable<Class> checkClass) {
-    checksByRepository.add(checkFactory
-      .<JavaScriptCheck>create(repositoryKey)
-      .addAnnotatedChecks(checkClass));
-
-    return this;
-  }
-
-  public JavaScriptChecks addCustomChecks(@Nullable CustomJavaScriptRulesDefinition[] customRulesDefinitions) {
-    if (customRulesDefinitions != null) {
-
-      for (CustomJavaScriptRulesDefinition rulesDefinition : customRulesDefinitions) {
-        addChecks(rulesDefinition.repositoryKey(), Lists.newArrayList(rulesDefinition.checkClasses()));
-      }
-    }
-
-    return this;
-  }
-
-  private List<JavaScriptCheck> all() {
-    List<JavaScriptCheck> allVisitors = Lists.newArrayList();
-
-    for (Checks<JavaScriptCheck> checks : checksByRepository) {
-      allVisitors.addAll(checks.all());
-    }
-
-    return allVisitors;
-  }
-
-  public List<SeCheck> seChecks() {
-    List<SeCheck> checks = new ArrayList<>();
-    for (JavaScriptCheck check : all()) {
-      if (check instanceof SeCheck) {
-        checks.add((SeCheck) check);
-      }
-    }
-
-    return checks;
-  }
-
-  public List<TreeVisitor> visitorChecks() {
-    List<TreeVisitor> checks = new ArrayList<>();
-    for (JavaScriptCheck check : all()) {
-      if (check instanceof TreeVisitor) {
-        checks.add((TreeVisitor) check);
-      }
-    }
-
-    return checks;
-  }
-
-  @Nullable
-  public RuleKey ruleKeyFor(JavaScriptCheck check) {
-    RuleKey ruleKey;
-
-    for (Checks<JavaScriptCheck> checks : checksByRepository) {
-      ruleKey = checks.ruleKey(check);
-
-      if (ruleKey != null) {
-        return ruleKey;
-      }
-    }
-    return null;
-  }
-
-}
\ No newline at end of file
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/AverageLineLengthCalculator.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/AverageLineLengthCalculator.java
deleted file mode 100644 (file)
index 8cdc3b2..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package de.example.plugins.custom.javascript.minify;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import org.sonar.squidbridge.api.AnalysisException;
-
-/**
- * An instance of this class computes the average line length of file.
- * Before making the computation, it discards all lines which are part
- * of the header comment.
- * The header comment is a comment which starts on the first line of the file.
- * It may be either a C-like comment (i.e., it starts with <code>"/*"</code>) or a C++-like comment
- * (i.e., it starts with <code>"//"</code>).
- */
-class AverageLineLengthCalculator {
-
-  private File file;
-
-  private boolean isAtFirstLine = true;
-
-  private boolean isInHeaderComment = false;
-
-  private boolean isClike = false;
-
-  private Charset encoding;
-
-  public AverageLineLengthCalculator(File file, Charset encoding) {
-    this.file = file;
-    this.encoding = encoding;
-  }
-
-  public int getAverageLineLength() {
-    long nbLines = 0;
-    long nbCharacters = 0;
-
-    try (BufferedReader reader = getReader(file)) {
-      String line;
-      while ((line = reader.readLine()) != null) {
-        if (!isLineInHeaderComment(line)) {
-          nbLines++;
-          nbCharacters += line.length();
-        }
-      }
-    } catch (IOException e) {
-      handleException(e, file);
-    }
-
-    return nbLines > 0 ? (int) (nbCharacters / nbLines) : 0;
-  }
-
-  public boolean isLineInHeaderComment(String line) {
-    String trimmedLine = line.trim();
-    if (isAtFirstLine) {
-      isAtFirstLine = false;
-      return isFirstLineInHeaderComment(trimmedLine);
-    } else if (isInHeaderComment) {
-      return isSubsequentLineInHeaderComment(trimmedLine);
-    }
-    return false;
-  }
-
-  private boolean isFirstLineInHeaderComment(String line) {
-    if (line.startsWith("/*")) {
-      isClike = true;
-      isInHeaderComment = !line.endsWith("*/");
-      return true;
-    } else if (line.startsWith("//")) {
-      isClike = false;
-      isInHeaderComment = true;
-      return true;
-    }
-    return false;
-  }
-
-  private boolean isSubsequentLineInHeaderComment(String line) {
-    if (isClike) {
-      if (line.endsWith("*/")) {
-        isInHeaderComment = false;
-      } else if (line.contains("*/")) {
-        // case of */ followed with something, possibly a long minified line
-        isInHeaderComment = false;
-        return false;
-      }
-      return true;
-    } else {
-      if (line.startsWith("//")) {
-        return true;
-      } else {
-        isInHeaderComment = false;
-        return false;
-      }
-    }
-  }
-
-  private BufferedReader getReader(File file) throws IOException {
-    return new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
-  }
-
-  private static void handleException(IOException e, File file) {
-    throw new AnalysisException("Unable to analyse file: " + file.getAbsolutePath(), e);
-  }
-
-}
\ No newline at end of file
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/MinificationAssessor.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/main/java/de/example/plugins/custom/javascript/minify/MinificationAssessor.java
deleted file mode 100644 (file)
index c0cbffa..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package de.example.plugins.custom.javascript.minify;
-
-import java.io.File;
-import java.nio.charset.Charset;
-
-/**
- * An object to assess if a .js file is a minified file or not.
- * <p>
- * An instance of this class is likely to consider as minified a .js file that,
- * although formally not minified, has an unusually high average line length.
- * This situation is typical of files that have been generated by some tool.
- * Such files are of poor interest as regards a SonarQube analysis.
- */
-public class MinificationAssessor {
-
-  private static final int DEFAULT_AVERAGE_LINE_LENGTH_THRESHOLD = 200;
-
-  private Charset encoding;
-
-  /**
-   * Value of the average line length 
-   * (= number of chars in the file / number of lines in the file)
-   * below which a file is not assessed as being a minified file.   
-   */
-  private int averageLineLengthThreshold;
-
-  public MinificationAssessor(Charset encoding) {
-    this(encoding, DEFAULT_AVERAGE_LINE_LENGTH_THRESHOLD);
-  }
-
-  public MinificationAssessor(Charset encoding, int averageLineLengthThreshold) {
-    this.encoding = encoding;
-    this.averageLineLengthThreshold = averageLineLengthThreshold;
-  }
-
-  public boolean isMinified(File file) {
-    return isJavaScriptFile(file) &&
-      (hasMinifiedFileName(file) || hasExcessiveAverageLineLength(file));
-  }
-
-  private static boolean hasMinifiedFileName(File file) {
-    String fileName = file.getName();
-    return fileName.endsWith("-min.js") || fileName.endsWith(".min.js");
-  }
-
-  private static boolean isJavaScriptFile(File file) {
-    return file.getName().endsWith(".js");
-  }
-
-  private boolean hasExcessiveAverageLineLength(File file) {
-    int averageLineLength = new AverageLineLengthCalculator(file, encoding).getAverageLineLength();
-    return averageLineLength > averageLineLengthThreshold;
-  }
-
-}
\ No newline at end of file