Skip to content

Commit 6905b08

Browse files
committed
Remove workarounds that are no longer required with Roslyn 1.1
1 parent b308353 commit 6905b08

6 files changed

Lines changed: 4 additions & 349 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/Helpers/FixAllContextHelper.cs

Lines changed: 2 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,18 @@
33

44
namespace StyleCop.Analyzers.Helpers
55
{
6-
using System;
76
using System.Collections.Concurrent;
87
using System.Collections.Generic;
98
using System.Collections.Immutable;
109
using System.Linq;
11-
using System.Reflection;
1210
using System.Threading;
1311
using System.Threading.Tasks;
1412
using Microsoft.CodeAnalysis;
1513
using Microsoft.CodeAnalysis.CodeFixes;
1614
using Microsoft.CodeAnalysis.Diagnostics;
17-
using Microsoft.CodeAnalysis.Text;
1815

1916
internal static class FixAllContextHelper
2017
{
21-
private static readonly ImmutableDictionary<string, ImmutableArray<Type>> DiagnosticAnalyzers = GetAllAnalyzers();
22-
23-
private static readonly Func<CompilationWithAnalyzers, SyntaxTree, CancellationToken, Task<ImmutableArray<Diagnostic>>> GetAnalyzerSyntaxDiagnosticsAsync;
24-
private static readonly Func<CompilationWithAnalyzers, SemanticModel, TextSpan?, CancellationToken, Task<ImmutableArray<Diagnostic>>> GetAnalyzerSemanticDiagnosticsAsync;
25-
private static readonly Func<CompilationWithAnalyzers, ImmutableArray<DiagnosticAnalyzer>, CancellationToken, Task<ImmutableArray<Diagnostic>>> GetAnalyzerCompilationDiagnosticsAsync;
26-
27-
static FixAllContextHelper()
28-
{
29-
Version roslynVersion = typeof(AdditionalText).GetTypeInfo().Assembly.GetName().Version;
30-
bool avoidGetAnalyzerDiagnosticsAsync = roslynVersion >= new Version(1, 1, 0, 0) && roslynVersion < new Version(1, 2, 0, 0);
31-
if (avoidGetAnalyzerDiagnosticsAsync)
32-
{
33-
var methodInfo = typeof(CompilationWithAnalyzers).GetRuntimeMethod(nameof(GetAnalyzerSyntaxDiagnosticsAsync), new[] { typeof(SyntaxTree), typeof(CancellationToken) });
34-
GetAnalyzerSyntaxDiagnosticsAsync = (Func<CompilationWithAnalyzers, SyntaxTree, CancellationToken, Task<ImmutableArray<Diagnostic>>>)methodInfo?.CreateDelegate(typeof(Func<CompilationWithAnalyzers, SyntaxTree, CancellationToken, Task<ImmutableArray<Diagnostic>>>));
35-
36-
methodInfo = typeof(CompilationWithAnalyzers).GetRuntimeMethod(nameof(GetAnalyzerSemanticDiagnosticsAsync), new[] { typeof(SemanticModel), typeof(TextSpan?), typeof(CancellationToken) });
37-
GetAnalyzerSemanticDiagnosticsAsync = (Func<CompilationWithAnalyzers, SemanticModel, TextSpan?, CancellationToken, Task<ImmutableArray<Diagnostic>>>)methodInfo?.CreateDelegate(typeof(Func<CompilationWithAnalyzers, SemanticModel, TextSpan?, CancellationToken, Task<ImmutableArray<Diagnostic>>>));
38-
39-
methodInfo = typeof(CompilationWithAnalyzers).GetRuntimeMethod(nameof(GetAnalyzerCompilationDiagnosticsAsync), new[] { typeof(ImmutableArray<DiagnosticAnalyzer>), typeof(CancellationToken) });
40-
GetAnalyzerCompilationDiagnosticsAsync = (Func<CompilationWithAnalyzers, ImmutableArray<DiagnosticAnalyzer>, CancellationToken, Task<ImmutableArray<Diagnostic>>>)methodInfo?.CreateDelegate(typeof(Func<CompilationWithAnalyzers, ImmutableArray<DiagnosticAnalyzer>, CancellationToken, Task<ImmutableArray<Diagnostic>>>));
41-
}
42-
}
43-
4418
public static async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
4519
{
4620
var allDiagnostics = ImmutableArray<Diagnostic>.Empty;
@@ -132,87 +106,7 @@ public static async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>
132106

133107
public static async Task<ImmutableArray<Diagnostic>> GetAllDiagnosticsAsync(Compilation compilation, CompilationWithAnalyzers compilationWithAnalyzers, ImmutableArray<DiagnosticAnalyzer> analyzers, IEnumerable<Document> documents, bool includeCompilerDiagnostics, CancellationToken cancellationToken)
134108
{
135-
if (GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null)
136-
{
137-
// In everything except Roslyn 1.1, we use GetAllDiagnosticsAsync and return the result.
138-
var allDiagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false);
139-
return allDiagnostics;
140-
}
141-
142-
compilationWithAnalyzers.Compilation.GetDeclarationDiagnostics(cancellationToken);
143-
144-
// Note that the following loop to obtain syntax and semantic diagnostics for each document cannot operate
145-
// on parallel due to our use of a single CompilationWithAnalyzers instance.
146-
var diagnostics = ImmutableArray.CreateBuilder<Diagnostic>();
147-
foreach (var document in documents)
148-
{
149-
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
150-
var syntaxDiagnostics = await GetAnalyzerSyntaxDiagnosticsAsync(compilationWithAnalyzers, syntaxTree, cancellationToken).ConfigureAwait(false);
151-
diagnostics.AddRange(syntaxDiagnostics);
152-
153-
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
154-
var semanticDiagnostics = await GetAnalyzerSemanticDiagnosticsAsync(compilationWithAnalyzers, semanticModel, default(TextSpan?), cancellationToken).ConfigureAwait(false);
155-
diagnostics.AddRange(semanticDiagnostics);
156-
}
157-
158-
foreach (var analyzer in analyzers)
159-
{
160-
diagnostics.AddRange(await GetAnalyzerCompilationDiagnosticsAsync(compilationWithAnalyzers, ImmutableArray.Create(analyzer), cancellationToken).ConfigureAwait(false));
161-
}
162-
163-
if (includeCompilerDiagnostics)
164-
{
165-
// This is the special handling for cases where code fixes operate on warnings produced by the C#
166-
// compiler, as opposed to being created by specific analyzers.
167-
var compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);
168-
diagnostics.AddRange(compilerDiagnostics);
169-
}
170-
171-
return diagnostics.ToImmutable();
172-
}
173-
174-
private static ImmutableDictionary<string, ImmutableArray<Type>> GetAllAnalyzers()
175-
{
176-
Assembly assembly = typeof(NoCodeFixAttribute).GetTypeInfo().Assembly;
177-
178-
var diagnosticAnalyzerType = typeof(DiagnosticAnalyzer);
179-
180-
var analyzers = ImmutableDictionary.CreateBuilder<string, ImmutableArray<Type>>();
181-
182-
foreach (var type in assembly.DefinedTypes)
183-
{
184-
if (type.IsSubclassOf(diagnosticAnalyzerType) && !type.IsAbstract)
185-
{
186-
Type analyzerType = type.AsType();
187-
DiagnosticAnalyzer analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(analyzerType);
188-
foreach (var descriptor in analyzer.SupportedDiagnostics)
189-
{
190-
ImmutableArray<Type> types;
191-
if (analyzers.TryGetValue(descriptor.Id, out types))
192-
{
193-
types = types.Add(analyzerType);
194-
}
195-
else
196-
{
197-
types = ImmutableArray.Create(analyzerType);
198-
}
199-
200-
analyzers[descriptor.Id] = types;
201-
}
202-
}
203-
}
204-
205-
return analyzers.ToImmutable();
206-
}
207-
208-
private static ImmutableArray<DiagnosticAnalyzer> GetDiagnosticAnalyzersForContext(FixAllContext fixAllContext)
209-
{
210-
return DiagnosticAnalyzers
211-
.Where(x => fixAllContext.DiagnosticIds.Contains(x.Key))
212-
.SelectMany(x => x.Value)
213-
.Distinct()
214-
.Select(type => (DiagnosticAnalyzer)Activator.CreateInstance(type))
215-
.ToImmutableArray();
109+
return await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false);
216110
}
217111

218112
/// <summary>
@@ -225,32 +119,7 @@ private static ImmutableArray<DiagnosticAnalyzer> GetDiagnosticAnalyzersForConte
225119
/// successfully, the <see cref="Task{TResult}.Result"/> will contain the requested diagnostics.</returns>
226120
private static async Task<ImmutableArray<Diagnostic>> GetAllDiagnosticsAsync(FixAllContext fixAllContext, Project project)
227121
{
228-
if (GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null)
229-
{
230-
return await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
231-
}
232-
233-
/*
234-
* The rest of this method is workaround code for issues with Roslyn 1.1...
235-
*/
236-
237-
var analyzers = GetDiagnosticAnalyzersForContext(fixAllContext);
238-
239-
// Most code fixes in this project operate on diagnostics reported by analyzers in this project. However, a
240-
// few code fixes also operate on standard warnings produced by the C# compiler. Special handling is
241-
// required for the latter case since these warnings are not considered "analyzer diagnostics".
242-
bool includeCompilerDiagnostics = fixAllContext.DiagnosticIds.Any(x => x.StartsWith("CS", StringComparison.Ordinal));
243-
244-
// Use a single CompilationWithAnalyzers for the entire operation. This allows us to use the
245-
// GetDeclarationDiagnostics workaround for dotnet/roslyn#7446 a single time, rather than once per document.
246-
var compilation = await project.GetCompilationAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
247-
var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, fixAllContext.CancellationToken);
248-
ImmutableArray<Diagnostic> diagnostics = await GetAllDiagnosticsAsync(compilation, compilationWithAnalyzers, analyzers, project.Documents, includeCompilerDiagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);
249-
250-
// Make sure to filter the results to the set requested for the Fix All operation, since analyzers can
251-
// report diagnostics with different IDs.
252-
diagnostics = diagnostics.RemoveAll(x => !fixAllContext.DiagnosticIds.Contains(x.Id));
253-
return diagnostics;
122+
return await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
254123
}
255124

256125
private static async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync(

StyleCop.Analyzers/StyleCop.Analyzers/Settings/SettingsHelper.cs

Lines changed: 2 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@
33

44
namespace StyleCop.Analyzers
55
{
6-
using System;
7-
using System.Collections.Concurrent;
86
using System.Collections.Immutable;
97
using System.IO;
10-
using System.Linq;
11-
using System.Reflection;
12-
using System.Runtime.ExceptionServices;
138
using System.Threading;
149
using Microsoft.CodeAnalysis;
1510
using Microsoft.CodeAnalysis.Diagnostics;
@@ -28,20 +23,6 @@ internal static class SettingsHelper
2823
new SourceTextValueProvider<StyleCopSettings>(
2924
text => GetStyleCopSettings(text, DeserializationFailureBehavior.ReturnDefaultSettings));
3025

31-
private static readonly bool AvoidAdditionalTextGetText;
32-
33-
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>> FieldInfos =
34-
new ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>>();
35-
36-
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, PropertyInfo>> PropertyInfos =
37-
new ConcurrentDictionary<Type, ConcurrentDictionary<string, PropertyInfo>>();
38-
39-
static SettingsHelper()
40-
{
41-
// dotnet/roslyn#6596 was fixed for Roslyn 1.2
42-
AvoidAdditionalTextGetText = typeof(AdditionalText).GetTypeInfo().Assembly.GetName().Version < new Version(1, 2, 0, 0);
43-
}
44-
4526
/// <summary>
4627
/// Gets the StyleCop settings.
4728
/// </summary>
@@ -162,7 +143,7 @@ private static SourceText TryGetStyleCopSettingsText(this AnalyzerOptions option
162143
{
163144
if (Path.GetFileName(additionalFile.Path).ToLowerInvariant() == SettingsFileName)
164145
{
165-
return GetText(additionalFile, cancellationToken);
146+
return additionalFile.GetText(cancellationToken);
166147
}
167148
}
168149

@@ -177,7 +158,7 @@ private static StyleCopSettings GetStyleCopSettings(ImmutableArray<AdditionalTex
177158
{
178159
if (Path.GetFileName(additionalFile.Path).ToLowerInvariant() == SettingsFileName)
179160
{
180-
SourceText additionalTextContent = GetText(additionalFile, cancellationToken);
161+
SourceText additionalTextContent = additionalFile.GetText(cancellationToken);
181162
var root = JsonConvert.DeserializeObject<SettingsFile>(additionalTextContent.ToString());
182163
return root.Settings;
183164
}
@@ -190,95 +171,5 @@ private static StyleCopSettings GetStyleCopSettings(ImmutableArray<AdditionalTex
190171

191172
return new StyleCopSettings();
192173
}
193-
194-
/// <summary>
195-
/// This code works around dotnet/roslyn#6596 by using reflection APIs to bypass the problematic method while
196-
/// reading the content of an <see cref="AdditionalText"/> file. If the reflection approach fails, the code
197-
/// falls back to the previous behavior.
198-
/// </summary>
199-
/// <param name="additionalText">The additional text to read.</param>
200-
/// <param name="cancellationToken">The cancellation token that the operation will observe.</param>
201-
/// <returns>The content of the additional text file.</returns>
202-
private static SourceText GetText(AdditionalText additionalText, CancellationToken cancellationToken)
203-
{
204-
if (AvoidAdditionalTextGetText)
205-
{
206-
object document = GetField(additionalText, "_document");
207-
if (document != null)
208-
{
209-
object textSource = GetField(document, "textSource");
210-
if (textSource != null)
211-
{
212-
object textAndVersion = CallMethod(textSource, "GetValue", new[] { typeof(CancellationToken) }, cancellationToken);
213-
if (textAndVersion != null)
214-
{
215-
SourceText text = GetProperty(textAndVersion, "Text") as SourceText;
216-
if (text != null)
217-
{
218-
return text;
219-
}
220-
}
221-
}
222-
}
223-
}
224-
225-
return additionalText.GetText(cancellationToken);
226-
}
227-
228-
private static object GetField(object obj, string name)
229-
{
230-
if (obj == null)
231-
{
232-
return null;
233-
}
234-
235-
ConcurrentDictionary<string, FieldInfo> fieldsForType = FieldInfos.GetOrAdd(obj.GetType(), _ => new ConcurrentDictionary<string, FieldInfo>());
236-
FieldInfo fieldInfo;
237-
if (!fieldsForType.TryGetValue(name, out fieldInfo))
238-
{
239-
fieldInfo = fieldsForType.GetOrAdd(name, _ => obj.GetType().GetRuntimeFields().FirstOrDefault(i => i.Name == name));
240-
}
241-
242-
return fieldInfo?.GetValue(obj);
243-
}
244-
245-
private static object CallMethod(object obj, string name, Type[] parameters, params object[] arguments)
246-
{
247-
try
248-
{
249-
MethodInfo methodInfo = obj?.GetType().GetRuntimeMethod(name, parameters);
250-
return methodInfo?.Invoke(obj, arguments);
251-
}
252-
catch (TargetInvocationException ex)
253-
{
254-
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
255-
throw;
256-
}
257-
}
258-
259-
private static object GetProperty(object obj, string name)
260-
{
261-
if (obj == null)
262-
{
263-
return null;
264-
}
265-
266-
ConcurrentDictionary<string, PropertyInfo> propertiesForType = PropertyInfos.GetOrAdd(obj.GetType(), _ => new ConcurrentDictionary<string, PropertyInfo>());
267-
PropertyInfo propertyInfo;
268-
if (!propertiesForType.TryGetValue(name, out propertyInfo))
269-
{
270-
propertyInfo = propertiesForType.GetOrAdd(name, _ => obj.GetType().GetRuntimeProperty(name));
271-
}
272-
273-
try
274-
{
275-
return propertyInfo?.GetValue(obj);
276-
}
277-
catch (TargetInvocationException ex)
278-
{
279-
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
280-
throw;
281-
}
282-
}
283174
}
284175
}

StyleCop.Analyzers/StyleCop.Analyzers/SpecialRules/SA0000Roslyn7446Workaround.cs

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)