Skip to content
This repository was archived by the owner on Apr 8, 2019. It is now read-only.

Commit 4e3311b

Browse files
authored
Merge pull request #13 from sharwell/update-roslyn
Update to Roslyn 1.2.1
2 parents cafcd66 + e47c931 commit 4e3311b

File tree

6 files changed

+7
-249
lines changed

6 files changed

+7
-249
lines changed

PublicApiAnalyzer/Directory.Build.props

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@
4747
-->
4848
<GenerateDocumentationFile>True</GenerateDocumentationFile>
4949
<NoWarn>$(NoWarn),1573,1591</NoWarn>
50-
51-
<!-- The referenced Roslyn API includes analyzers that completely fail. -->
52-
<NoWarn>$(NoWarn),AD0001</NoWarn>
5350
</PropertyGroup>
5451

5552
<ItemGroup>

PublicApiAnalyzer/PublicApiAnalyzer.CodeFixes/Helpers/FixAllContextHelper.cs

Lines changed: 2 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,14 @@ namespace PublicApiAnalyzer.Helpers
88
using System.Collections.Generic;
99
using System.Collections.Immutable;
1010
using System.Linq;
11-
using System.Reflection;
1211
using System.Threading;
1312
using System.Threading.Tasks;
1413
using Microsoft.CodeAnalysis;
1514
using Microsoft.CodeAnalysis.CodeFixes;
1615
using Microsoft.CodeAnalysis.Diagnostics;
17-
using Microsoft.CodeAnalysis.Text;
1816

1917
internal static class FixAllContextHelper
2018
{
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-
4419
public static async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
4520
{
4621
var allDiagnostics = ImmutableArray<Diagnostic>.Empty;
@@ -146,87 +121,7 @@ public static async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>
146121

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

232127
/// <summary>
@@ -239,32 +134,7 @@ private static ImmutableArray<DiagnosticAnalyzer> GetDiagnosticAnalyzersForConte
239134
/// successfully, the <see cref="Task{TResult}.Result"/> will contain the requested diagnostics.</returns>
240135
private static async Task<ImmutableArray<Diagnostic>> GetAllDiagnosticsAsync(FixAllContext fixAllContext, Project project)
241136
{
242-
if (GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null)
243-
{
244-
return await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
245-
}
246-
247-
/*
248-
* The rest of this method is workaround code for issues with Roslyn 1.1...
249-
*/
250-
251-
var analyzers = GetDiagnosticAnalyzersForContext(fixAllContext);
252-
253-
// Most code fixes in this project operate on diagnostics reported by analyzers in this project. However, a
254-
// few code fixes also operate on standard warnings produced by the C# compiler. Special handling is
255-
// required for the latter case since these warnings are not considered "analyzer diagnostics".
256-
bool includeCompilerDiagnostics = fixAllContext.DiagnosticIds.Any(x => x.StartsWith("CS", StringComparison.Ordinal));
257-
258-
// Use a single CompilationWithAnalyzers for the entire operation. This allows us to use the
259-
// GetDeclarationDiagnostics workaround for dotnet/roslyn#7446 a single time, rather than once per document.
260-
var compilation = await project.GetCompilationAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
261-
var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, fixAllContext.CancellationToken);
262-
ImmutableArray<Diagnostic> diagnostics = await GetAllDiagnosticsAsync(compilation, compilationWithAnalyzers, analyzers, project.Documents, includeCompilerDiagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);
263-
264-
// Make sure to filter the results to the set requested for the Fix All operation, since analyzers can
265-
// report diagnostics with different IDs.
266-
diagnostics = diagnostics.RemoveAll(x => !fixAllContext.DiagnosticIds.Contains(x.Id));
267-
return diagnostics;
137+
return await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
268138
}
269139

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

PublicApiAnalyzer/PublicApiAnalyzer.CodeFixes/PublicApiAnalyzer.CodeFixes.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
</PropertyGroup>
3434

3535
<ItemGroup>
36-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.0.0" />
37-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="1.0.0" />
36+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.2.1" />
37+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="1.2.1" />
3838
</ItemGroup>
3939

4040
<ItemGroup>

PublicApiAnalyzer/PublicApiAnalyzer.Test/PublicApiAnalyzer.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Microsoft.CodeAnalysis" Version="1.0.0" />
18+
<PackageReference Include="Microsoft.CodeAnalysis" Version="1.2.1" />
1919
<PackageReference Include="xunit" Version="2.3.0-beta3-build3705" />
2020
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta3-build3705" PrivateAssets="all" />
2121
</ItemGroup>

PublicApiAnalyzer/PublicApiAnalyzer/PublicApiAnalyzer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</PropertyGroup>
3030

3131
<ItemGroup>
32-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.0.0" />
32+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.2.1" />
3333
</ItemGroup>
3434

3535
<ItemGroup>

PublicApiAnalyzer/PublicApiAnalyzer/Settings/SettingsHelper.cs

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@
33

44
namespace PublicApiAnalyzer
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;
@@ -22,20 +17,6 @@ internal static class SettingsHelper
2217
{
2318
internal const string PublicApiFileName = "PublicAPI.Unshipped.txt";
2419

25-
private static readonly bool AvoidAdditionalTextGetText;
26-
27-
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>> FieldInfos =
28-
new ConcurrentDictionary<Type, ConcurrentDictionary<string, FieldInfo>>();
29-
30-
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, PropertyInfo>> PropertyInfos =
31-
new ConcurrentDictionary<Type, ConcurrentDictionary<string, PropertyInfo>>();
32-
33-
static SettingsHelper()
34-
{
35-
// dotnet/roslyn#6596 was fixed for Roslyn 1.2
36-
AvoidAdditionalTextGetText = typeof(AdditionalText).GetTypeInfo().Assembly.GetName().Version < new Version(1, 2, 0, 0);
37-
}
38-
3920
/// <summary>
4021
/// Gets the public API text.
4122
/// </summary>
@@ -66,102 +47,12 @@ private static SourceText GetPublicApi(ImmutableArray<AdditionalText> additional
6647
{
6748
if (Path.GetFileName(additionalFile.Path).ToLowerInvariant() == PublicApiFileName)
6849
{
69-
SourceText additionalTextContent = GetText(additionalFile, cancellationToken);
50+
SourceText additionalTextContent = additionalFile.GetText(cancellationToken);
7051
return additionalTextContent;
7152
}
7253
}
7354

7455
return null;
7556
}
76-
77-
/// <summary>
78-
/// This code works around dotnet/roslyn#6596 by using reflection APIs to bypass the problematic method while
79-
/// reading the content of an <see cref="AdditionalText"/> file. If the reflection approach fails, the code
80-
/// falls back to the previous behavior.
81-
/// </summary>
82-
/// <param name="additionalText">The additional text to read.</param>
83-
/// <param name="cancellationToken">The cancellation token that the operation will observe.</param>
84-
/// <returns>The content of the additional text file.</returns>
85-
private static SourceText GetText(AdditionalText additionalText, CancellationToken cancellationToken)
86-
{
87-
if (AvoidAdditionalTextGetText)
88-
{
89-
object document = GetField(additionalText, "_document");
90-
if (document != null)
91-
{
92-
object textSource = GetField(document, "textSource");
93-
if (textSource != null)
94-
{
95-
object textAndVersion = CallMethod(textSource, "GetValue", new[] { typeof(CancellationToken) }, cancellationToken);
96-
if (textAndVersion != null)
97-
{
98-
SourceText text = GetProperty(textAndVersion, "Text") as SourceText;
99-
if (text != null)
100-
{
101-
return text;
102-
}
103-
}
104-
}
105-
}
106-
}
107-
108-
return additionalText.GetText(cancellationToken);
109-
}
110-
111-
private static object GetField(object obj, string name)
112-
{
113-
if (obj == null)
114-
{
115-
return null;
116-
}
117-
118-
ConcurrentDictionary<string, FieldInfo> fieldsForType = FieldInfos.GetOrAdd(obj.GetType(), _ => new ConcurrentDictionary<string, FieldInfo>());
119-
FieldInfo fieldInfo;
120-
if (!fieldsForType.TryGetValue(name, out fieldInfo))
121-
{
122-
fieldInfo = fieldsForType.GetOrAdd(name, _ => obj.GetType().GetRuntimeFields().FirstOrDefault(i => i.Name == name));
123-
}
124-
125-
return fieldInfo?.GetValue(obj);
126-
}
127-
128-
private static object CallMethod(object obj, string name, Type[] parameters, params object[] arguments)
129-
{
130-
try
131-
{
132-
MethodInfo methodInfo = obj?.GetType().GetRuntimeMethod(name, parameters);
133-
return methodInfo?.Invoke(obj, arguments);
134-
}
135-
catch (TargetInvocationException ex)
136-
{
137-
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
138-
throw;
139-
}
140-
}
141-
142-
private static object GetProperty(object obj, string name)
143-
{
144-
if (obj == null)
145-
{
146-
return null;
147-
}
148-
149-
ConcurrentDictionary<string, PropertyInfo> propertiesForType = PropertyInfos.GetOrAdd(obj.GetType(), _ => new ConcurrentDictionary<string, PropertyInfo>());
150-
PropertyInfo propertyInfo;
151-
if (!propertiesForType.TryGetValue(name, out propertyInfo))
152-
{
153-
propertyInfo = propertiesForType.GetOrAdd(name, _ => obj.GetType().GetRuntimeProperty(name));
154-
}
155-
156-
try
157-
{
158-
return propertyInfo?.GetValue(obj);
159-
}
160-
catch (TargetInvocationException ex)
161-
{
162-
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
163-
throw;
164-
}
165-
}
16657
}
16758
}

0 commit comments

Comments
 (0)