Skip to content
This repository has been archived by the owner on Jul 12, 2022. It is now read-only.

Custom analyzer fixes for PR 217 #227

Merged
merged 2 commits into from
Apr 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 25 additions & 15 deletions src/CodeFormatter/FormatOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal class CommandLineOptions
{
[Value(
0,
HelpText = "Project, solution or response file to drive code formatting.",
HelpText = "Project, solution, text file with target paths, or response file to drive code formatting.",
Required = true)]
public IEnumerable<string> Targets { get; set; }

Expand Down Expand Up @@ -67,9 +67,9 @@ internal class CommandLineOptions
public bool UseAnalyzers { get; set; }

[Option(
"analyzer-list",
HelpText = "A file containing a newline separated list of analyzer assemblies to be run against the target source.")]
public string AnalyzerListFile { get; set; }
"analyzers",
HelpText = "A path to an analyzer assembly or a file containing a newline separated list of analyzer assemblies to be run against the target source.")]
public string TargetAnalyzers { get; set; }

[Option(
"log-output-path",
Expand All @@ -78,33 +78,43 @@ internal class CommandLineOptions

public virtual bool ApplyFixes { get; }

private ImmutableArray<string> _analyzerListText;
public ImmutableArray<string> AnalyzerListText
private ImmutableArray<string> _targetAnalyzerText;
public ImmutableArray<string> TargetAnalyzerText
{
get
{
if (_analyzerListText == null)
if (_targetAnalyzerText == null)
{
_analyzerListText = InitializeAnalyzerListText(AnalyzerListFile);
_targetAnalyzerText = InitializeTargetAnalyzerText(TargetAnalyzers);
}
return _analyzerListText;
return _targetAnalyzerText;
}
internal set
{
_analyzerListText = value;
_targetAnalyzerText = value;
}
}

private static ImmutableArray<string> InitializeAnalyzerListText(string analyzerListFile)
private static ImmutableArray<string> InitializeTargetAnalyzerText(string targetAnalyzers)
{
ImmutableArray<string> analyzerListText = new ImmutableArray<string>();
var fileType = Path.GetExtension(targetAnalyzers);

if (!String.IsNullOrEmpty(analyzerListFile))
if (StringComparer.OrdinalIgnoreCase.Equals(fileType, ".dll"))
{
analyzerListText = ImmutableArray.CreateRange(File.ReadAllLines(analyzerListFile));
return ImmutableArray.Create(targetAnalyzers);
}
else if(StringComparer.OrdinalIgnoreCase.Equals(fileType, ".txt"))
{
ImmutableArray<string> analyzerText = new ImmutableArray<string>();

if (!String.IsNullOrEmpty(targetAnalyzers))
{
analyzerText = ImmutableArray.CreateRange(File.ReadAllLines(targetAnalyzers));
}
return analyzerText;
}

return analyzerListText;
return ImmutableArray<string>.Empty;
}

private ImmutableArray<string> _copyrightHeaderText;
Expand Down
54 changes: 32 additions & 22 deletions src/CodeFormatter/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,36 @@ private static ImmutableArray<DiagnosticAnalyzer> LoadAnalyzersFromAssembly(stri
}
return newAnalyzers;
}

// Expects a list of paths to files or directories of DLLs containing analyzers and adds them to the engine
internal static ImmutableArray<DiagnosticAnalyzer> AddCustomAnalyzers(IFormattingEngine engine, ImmutableArray<string> analyzerList)
{
foreach (var analyzerPath in analyzerList)
{
if (File.Exists(analyzerPath))
{
var newAnalyzers = LoadAnalyzersFromAssembly(analyzerPath, true);
engine.AddAnalyzers(newAnalyzers);
return newAnalyzers;
}
else if (Directory.Exists(analyzerPath))
{
var DLLs = Directory.GetFiles(analyzerPath, "*.dll");
foreach (var dll in DLLs)
{
// allows specifying a folder that contains analyzers as well as non-analyzer DLLs without throwing
var newAnalyzers = LoadAnalyzersFromAssembly(dll, false);
if (newAnalyzers.Count() > 0)
{
engine.AddAnalyzers(newAnalyzers);
}
return newAnalyzers;
}
}
}

return ImmutableArray<DiagnosticAnalyzer>.Empty;
}

private static async Task<int> RunAsync(CommandLineOptions options, CancellationToken cancellationToken)
{
Expand All @@ -166,29 +196,9 @@ private static async Task<int> RunAsync(CommandLineOptions options, Cancellation
engine.ApplyFixes = options.ApplyFixes;
engine.LogOutputPath = options.LogOutputPath;

if (options.AnalyzerListFile != null && options.AnalyzerListText != null && options.AnalyzerListText.Count() > 0)
if (options.TargetAnalyzers != null && options.TargetAnalyzerText != null && options.TargetAnalyzerText.Count() > 0)
{
foreach (var analyzerPath in options.AnalyzerListText)
{
if (File.Exists(analyzerPath))
{
var newAnalyzers = LoadAnalyzersFromAssembly(analyzerPath, true);
engine.AddAnalyzers(newAnalyzers);
}
else if (Directory.Exists(analyzerPath))
{
var DLLs = Directory.GetFiles(analyzerPath, "*.dll");
foreach (var dll in DLLs)
{
// allows specifying a folder that contains analyzers as well as non-analyzer DLLs without throwing
var newAnalyzers = LoadAnalyzersFromAssembly(dll, false);
if (newAnalyzers.Count() > 0)
{
engine.AddAnalyzers(newAnalyzers);
}
}
}
}
AddCustomAnalyzers(engine, options.TargetAnalyzerText);
}

// Analyzers will hydrate rule enabled/disabled settings
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -20,46 +21,61 @@ public class FormattingEngineCreationTests
typeof(FormattingEngine).Assembly,
typeof(OptimizeNamespaceImportsAnalyzer).Assembly
};
// TODO: fix hardcoded path
private static string TestDLLDir = @"E:\src\codeformatter\src\Microsoft.DotNet.CodeFormatting.Tests\TestAnalyzers\";
private static Assembly RoslynV100Analyzer = Assembly.LoadFile(TestDLLDir + "RoslynV100Analyzer.dll");
private static Assembly RoslynV110Analyzer = Assembly.LoadFile(TestDLLDir + "RoslynV110Analyzer.dll");
private static Assembly RoslynV111Analyzer = Assembly.LoadFile(TestDLLDir + "RoslynV111Analyzer.dll");
private static Assembly RoslynV120Beta1Analyzer = Assembly.LoadFile(TestDLLDir + "RoslynV120Beta1Analyzer.dll");

private static string TestDLLDir = Path.Combine(Directory.GetCurrentDirectory(), "TestAnalyzers");
private static string RoslynV100Analyzer = Path.Combine(TestDLLDir, "RoslynV100Analyzer.dll");
private static string RoslynV110Analyzer = Path.Combine(TestDLLDir, "RoslynV110Analyzer.dll");
private static string RoslynV111Analyzer = Path.Combine(TestDLLDir, "RoslynV111Analyzer.dll");
private static string RoslynV120Beta1Analyzer = Path.Combine(TestDLLDir, "RoslynV120Beta1Analyzer.dll");
private static string RoslynV120VBAnalyzer = Path.Combine(TestDLLDir, "RoslynV120VBAnalyzer.dll");

[Fact]
public void AnalyzersBuiltAgainstRoslynV100()
{
IEnumerable<Assembly> roslynV1AnalyzerDLL = new Assembly[] { RoslynV100Analyzer };
IFormattingEngine engine = FormattingEngine.Create(DefaultCompositionAssemblies);
Assert.DoesNotThrow(() => {
var assemblies = DefaultCompositionAssemblies.Concat(roslynV1AnalyzerDLL);
var analyzers = Program.AddCustomAnalyzers(engine, ImmutableArray.Create(RoslynV100Analyzer));
Assert.Equal(1, analyzers.Count());
});
}

[Fact]
public void AnalyzersBuiltAgainstRoslynV110()
{
IEnumerable<Assembly> roslynV110AnalyzerDLL = new Assembly[] { RoslynV110Analyzer };
IFormattingEngine engine = FormattingEngine.Create(DefaultCompositionAssemblies);
Assert.DoesNotThrow(() => {
var assemblies = DefaultCompositionAssemblies.Concat(roslynV110AnalyzerDLL);
var analyzers = Program.AddCustomAnalyzers(engine, ImmutableArray.Create(RoslynV110Analyzer));
Assert.Equal(1, analyzers.Count());
});
}

[Fact]
public void AnalyzersBuiltAgainstRoslynV111()
{
IEnumerable<Assembly> roslynV111AnalyzerDLL = new Assembly[] { RoslynV111Analyzer };
IFormattingEngine engine = FormattingEngine.Create(DefaultCompositionAssemblies);
Assert.DoesNotThrow(() => {
var assemblies = DefaultCompositionAssemblies.Concat(roslynV111AnalyzerDLL);
var analyzers = Program.AddCustomAnalyzers(engine, ImmutableArray.Create(RoslynV111Analyzer));
Assert.Equal(1, analyzers.Count());
});
}

[Fact]
public void AnalyzersBuiltAgainstRoslynV120Beta1()
{
IEnumerable<Assembly> roslynV120Beta1AnalyzerDLL = new Assembly[] { RoslynV120Beta1Analyzer };
IFormattingEngine engine = FormattingEngine.Create(DefaultCompositionAssemblies);
Assert.DoesNotThrow(() => {
var analyzers = Program.AddCustomAnalyzers(engine, ImmutableArray.Create(RoslynV120Beta1Analyzer));
Assert.Equal(1, analyzers.Count());
});
}

[Fact]
public void AnalyzersBuiltAgainstRoslynV120()
{
IFormattingEngine engine = FormattingEngine.Create(DefaultCompositionAssemblies);
Assert.DoesNotThrow(() => {
var assemblies = DefaultCompositionAssemblies.Concat(roslynV120Beta1AnalyzerDLL);
var analyzers = Program.AddCustomAnalyzers(engine, ImmutableArray.Create(RoslynV120VBAnalyzer));
Assert.Equal(1, analyzers.Count());
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,21 @@
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="TestAnalyzers\RoslynV120Beta1Analyzer.dll" />
<Content Include="TestAnalyzers\RoslynV111Analyzer.dll" />
<Content Include="TestAnalyzers\RoslynV110Analyzer.dll" />
<Content Include="TestAnalyzers\RoslynV100Analyzer.dll" />
<Content Include="TestAnalyzers\RoslynV120Beta1Analyzer.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="TestAnalyzers\RoslynV111Analyzer.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="TestAnalyzers\RoslynV110Analyzer.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="TestAnalyzers\RoslynV100Analyzer.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="TestAnalyzers\RoslynV120VBAnalyzer.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,11 @@ private async Task FormatWithAnalyzersCoreAsync(Workspace workspace, ProjectId p
foreach (var analyzer in analyzers)
{
var diags = await _compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(ImmutableArray.Create(analyzer), cancellationToken);

if (Verbose || LogOutputPath != null)
{
var analyzerTelemetryInfo = await _compilationWithAnalyzers.GetAnalyzerTelemetryInfoAsync(analyzer, cancellationToken);
FormatLogger.WriteLine("{0}\t{1}\t{2}\t{3}", project.Name, analyzer.ToString(), diags.Count(), analyzerTelemetryInfo.ExecutionTime);
var resultPath = Path.ChangeExtension(LogOutputPath + resultFile, "json");
LogDiagnostics(resultPath, diags);
}
Expand Down