public void Configuration() { var conf = new Configuration(XDocument.Load("TestResources\\ConfigurationTest.xml")); conf.IgnoreHeaderComments.Should().BeTrue(); conf.Files.Should().BeEquivalentTo("TestResources\\TestInput.cs"); conf.AnalyzerIds.Should().BeEquivalentTo( "S1121", "S2306", "S1227", "S104", "S1541", "S103", "S1479", "S1067", "S107", "S109", "S101", "S100", "S124"); var analyzers = conf.Analyzers(); analyzers.OfType<FileLines>().Single().Maximum.ShouldBeEquivalentTo(1000); analyzers.OfType<LineLength>().Single().Maximum.ShouldBeEquivalentTo(200); analyzers.OfType<TooManyLabelsInSwitch>().Single().Maximum.ShouldBeEquivalentTo(30); analyzers.OfType<TooManyParameters>().Single().Maximum.ShouldBeEquivalentTo(7); analyzers.OfType<ExpressionComplexity>().Single().Maximum.ShouldBeEquivalentTo(3); analyzers.OfType<FunctionComplexity>().Single().Maximum.ShouldBeEquivalentTo(10); analyzers.OfType<ClassName>().Single().Convention.ShouldBeEquivalentTo("^(?:[A-HJ-Z][a-zA-Z0-9]+|I[a-z0-9][a-zA-Z0-9]*)$"); analyzers.OfType<MethodName>().Single().Convention.ShouldBeEquivalentTo("^[A-Z][a-zA-Z0-9]+$"); analyzers.OfType<MagicNumber>().Single().Exceptions.ShouldBeEquivalentTo(ImmutableHashSet.Create("0", "1", "0x0", "0x00", ".0", ".1", "0.0", "1.0")); var commentAnalyzer = analyzers.OfType<CommentRegularExpression>().Single(); var ruleInstances = commentAnalyzer.RuleInstances.ToList(); ruleInstances.Should().HaveCount(2); ruleInstances[0].Descriptor.Id.ShouldBeEquivalentTo("TODO"); ruleInstances[0].Descriptor.MessageFormat.ToString().ShouldBeEquivalentTo("Fix this TODO"); ruleInstances[0].RegularExpression.ShouldBeEquivalentTo(".*TODO.*"); ruleInstances[1].Descriptor.Id.ShouldBeEquivalentTo("FIXME"); ruleInstances[1].Descriptor.MessageFormat.ToString().ShouldBeEquivalentTo("Fix this FIXME"); ruleInstances[1].RegularExpression.ShouldBeEquivalentTo(".*FIXME.*"); }
public static int Main(string[] args) { Write(string.Format("SonarLint version {0}", typeof (Program).Assembly.GetName().Version)); var configuration = new Configuration(XDocument.Load(args[0])); var diagnosticsRunner = new DiagnosticsRunner(configuration.Analyzers()); var xmlOutSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true, IndentChars = " " }; using (var xmlOut = XmlWriter.Create(args[1], xmlOutSettings)) { xmlOut.WriteComment("This XML format is not an API"); xmlOut.WriteStartElement("AnalysisOutput"); xmlOut.WriteStartElement("Files"); var n = 0; foreach (var file in configuration.Files) { xmlOut.Flush(); Write(n + "/" + configuration.Files.Count() + " files analyzed, starting to analyze: " + file); n++; try { var solution = CompilationHelper.GetSolutionFromFiles(file); var compilation = solution.Projects.First().GetCompilationAsync().Result; var syntaxTree = compilation.SyntaxTrees.First(); var metrics = new Metrics(syntaxTree); xmlOut.WriteStartElement("File"); xmlOut.WriteElementString("Path", file); xmlOut.WriteStartElement("Metrics"); xmlOut.WriteElementString("Lines", metrics.Lines().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("Classes", metrics.Classes().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("Accessors", metrics.Accessors().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("Statements", metrics.Statements().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("Functions", metrics.Functions().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("PublicApi", metrics.PublicApi().ToString(CultureInfo.InvariantCulture)); xmlOut.WriteElementString("PublicUndocumentedApi", metrics.PublicUndocumentedApi().ToString(CultureInfo.InvariantCulture)); var complexity = metrics.Complexity(); xmlOut.WriteElementString("Complexity", complexity.ToString(CultureInfo.InvariantCulture)); // TODO This is a bit ridiculous, but is how SonarQube works var fileComplexityDistribution = new Distribution(0, 5, 10, 20, 30, 60, 90); fileComplexityDistribution.Add(complexity); xmlOut.WriteElementString("FileComplexityDistribution", fileComplexityDistribution.ToString()); xmlOut.WriteElementString("FunctionComplexityDistribution", metrics.FunctionComplexityDistribution().ToString()); var comments = metrics.Comments(configuration.IgnoreHeaderComments); xmlOut.WriteStartElement("Comments"); xmlOut.WriteStartElement("NoSonar"); foreach (var line in comments.NoSonar) { xmlOut.WriteElementString("Line", line.ToString(CultureInfo.InvariantCulture)); } xmlOut.WriteEndElement(); xmlOut.WriteStartElement("NonBlank"); foreach (var line in comments.NonBlank) { xmlOut.WriteElementString("Line", line.ToString(CultureInfo.InvariantCulture)); } xmlOut.WriteEndElement(); xmlOut.WriteEndElement(); xmlOut.WriteStartElement("LinesOfCode"); foreach (var line in metrics.LinesOfCode()) { xmlOut.WriteElementString("Line", line.ToString(CultureInfo.InvariantCulture)); } xmlOut.WriteEndElement(); xmlOut.WriteEndElement(); xmlOut.WriteStartElement("Issues"); foreach (var diagnostic in diagnosticsRunner.GetDiagnostics(compilation)) { xmlOut.WriteStartElement("Issue"); xmlOut.WriteElementString("Id", diagnostic.Id); if (diagnostic.Location != Location.None) { xmlOut.WriteElementString("Line", (diagnostic.GetLineNumberToReport()).ToString(CultureInfo.InvariantCulture)); } xmlOut.WriteElementString("Message", diagnostic.GetMessage()); xmlOut.WriteEndElement(); } xmlOut.WriteEndElement(); xmlOut.WriteEndElement(); } catch (Exception e) { Console.Error.WriteLine("Failed to analyze the file: " + file); Console.Error.WriteLine(e); return 1; } } xmlOut.WriteEndElement(); xmlOut.WriteEndElement(); xmlOut.WriteEndDocument(); xmlOut.Flush(); return 0; } }