mirror of https://github.com/dotnet/runtime
Enable recently added analyzers (and fix some violations) (#67292)
This commit is contained in:
parent
38fe46837a
commit
b2e494c6ba
|
@ -205,6 +205,12 @@ dotnet_diagnostic.CA1418.severity = warning
|
|||
# CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'
|
||||
dotnet_diagnostic.CA1419.severity = warning
|
||||
|
||||
# CA1420: Property, type, or attribute requires runtime marshalling
|
||||
dotnet_diagnostic.CA1420.severity = warning
|
||||
|
||||
# CA1421: This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied
|
||||
dotnet_diagnostic.CA1421.severity = suggestion
|
||||
|
||||
# CA1501: Avoid excessive inheritance
|
||||
dotnet_diagnostic.CA1501.severity = none
|
||||
|
||||
|
@ -393,6 +399,9 @@ dotnet_diagnostic.CA1849.severity = suggestion
|
|||
# CA1850: Prefer static 'HashData' method over 'ComputeHash'
|
||||
dotnet_diagnostic.CA1850.severity = warning
|
||||
|
||||
# CA1851: Possible multiple enumerations of 'IEnumerable' collection
|
||||
dotnet_diagnostic.CA1851.severity = suggestion
|
||||
|
||||
# CA2000: Dispose objects before losing scope
|
||||
dotnet_diagnostic.CA2000.severity = none
|
||||
|
||||
|
@ -432,6 +441,9 @@ dotnet_diagnostic.CA2017.severity = warning
|
|||
# CA2018: 'Buffer.BlockCopy' expects the number of bytes to be copied for the 'count' argument
|
||||
dotnet_diagnostic.CA2018.severity = warning
|
||||
|
||||
# CA2019: Improper 'ThreadStatic' field initialization
|
||||
dotnet_diagnostic.CA2019.severity = warning
|
||||
|
||||
# CA2100: Review SQL queries for security vulnerabilities
|
||||
dotnet_diagnostic.CA2100.severity = none
|
||||
|
||||
|
@ -565,6 +577,9 @@ dotnet_diagnostic.CA2257.severity = warning
|
|||
# CA2258: Providing a 'DynamicInterfaceCastableImplementation' interface in Visual Basic is unsupported
|
||||
dotnet_diagnostic.CA2258.severity = warning
|
||||
|
||||
# CA2259: 'ThreadStatic' only affects static fields
|
||||
dotnet_diagnostic.CA2259.severity = warning
|
||||
|
||||
# CA2300: Do not use insecure deserializer BinaryFormatter
|
||||
dotnet_diagnostic.CA2300.severity = none
|
||||
|
||||
|
|
|
@ -204,6 +204,12 @@ dotnet_diagnostic.CA1418.severity = none
|
|||
# CA1419: Provide a parameterless constructor that is as visible as the containing type for concrete types derived from 'System.Runtime.InteropServices.SafeHandle'
|
||||
dotnet_diagnostic.CA1419.severity = none
|
||||
|
||||
# CA1420: Property, type, or attribute requires runtime marshalling
|
||||
dotnet_diagnostic.CA1420.severity = none
|
||||
|
||||
# CA1421: This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied
|
||||
dotnet_diagnostic.CA1421.severity = none
|
||||
|
||||
# CA1501: Avoid excessive inheritance
|
||||
dotnet_diagnostic.CA1501.severity = none
|
||||
|
||||
|
@ -390,6 +396,9 @@ dotnet_diagnostic.CA1849.severity = none
|
|||
# CA1850: Prefer static 'HashData' method over 'ComputeHash'
|
||||
dotnet_diagnostic.CA1850.severity = none
|
||||
|
||||
# CA1851: Possible multiple enumerations of 'IEnumerable' collection
|
||||
dotnet_diagnostic.CA1851.severity = none
|
||||
|
||||
# CA2000: Dispose objects before losing scope
|
||||
dotnet_diagnostic.CA2000.severity = none
|
||||
|
||||
|
@ -424,10 +433,13 @@ dotnet_diagnostic.CA2015.severity = none
|
|||
dotnet_diagnostic.CA2016.severity = none
|
||||
|
||||
# CA2017: Parameter count mismatch
|
||||
dotnet_diagnostic.CA2017.severity = warning
|
||||
dotnet_diagnostic.CA2017.severity = none
|
||||
|
||||
# CA2018: 'Buffer.BlockCopy' expects the number of bytes to be copied for the 'count' argument
|
||||
dotnet_diagnostic.CA2018.severity = warning
|
||||
dotnet_diagnostic.CA2018.severity = none
|
||||
|
||||
# CA2019: Improper 'ThreadStatic' field initialization
|
||||
dotnet_diagnostic.CA2019.severity = none
|
||||
|
||||
# CA2100: Review SQL queries for security vulnerabilities
|
||||
dotnet_diagnostic.CA2100.severity = none
|
||||
|
@ -550,16 +562,19 @@ dotnet_diagnostic.CA2253.severity = none
|
|||
dotnet_diagnostic.CA2254.severity = none
|
||||
|
||||
# CA2255: The 'ModuleInitializer' attribute should not be used in libraries
|
||||
dotnet_diagnostic.CA2255.severity = warning
|
||||
dotnet_diagnostic.CA2255.severity = none
|
||||
|
||||
# CA2256: All members declared in parent interfaces must have an implementation in a DynamicInterfaceCastableImplementation-attributed interface
|
||||
dotnet_diagnostic.CA2256.severity = warning
|
||||
dotnet_diagnostic.CA2256.severity = none
|
||||
|
||||
# CA2257: Members defined on an interface with the 'DynamicInterfaceCastableImplementationAttribute' should be 'static'
|
||||
dotnet_diagnostic.CA2257.severity = warning
|
||||
dotnet_diagnostic.CA2257.severity = none
|
||||
|
||||
# CA2258: Providing a 'DynamicInterfaceCastableImplementation' interface in Visual Basic is unsupported
|
||||
dotnet_diagnostic.CA2258.severity = warning
|
||||
dotnet_diagnostic.CA2258.severity = none
|
||||
|
||||
# CA2259: 'ThreadStatic' only affects static fields
|
||||
dotnet_diagnostic.CA2259.severity = none
|
||||
|
||||
# CA2300: Do not use insecure deserializer BinaryFormatter
|
||||
dotnet_diagnostic.CA2300.severity = none
|
||||
|
|
|
@ -190,9 +190,9 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
WriteAssetList(key, group.RuntimeFiles, jsonWriter);
|
||||
}
|
||||
|
||||
private static void AddDependencies(IEnumerable<Dependency> dependencies, Utf8JsonWriter jsonWriter)
|
||||
private static void AddDependencies(IReadOnlyCollection<Dependency> dependencies, Utf8JsonWriter jsonWriter)
|
||||
{
|
||||
if (!dependencies.Any())
|
||||
if (dependencies.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -205,16 +205,18 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
jsonWriter.WriteEndObject();
|
||||
}
|
||||
|
||||
private static void AddResourceAssemblies(IEnumerable<ResourceAssembly> resourceAssemblies, Utf8JsonWriter jsonWriter)
|
||||
private static void AddResourceAssemblies(IReadOnlyList<ResourceAssembly> resourceAssemblies, Utf8JsonWriter jsonWriter)
|
||||
{
|
||||
if (!resourceAssemblies.Any())
|
||||
int count = resourceAssemblies.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
jsonWriter.WriteStartObject(DependencyContextStrings.ResourceAssembliesPropertyName);
|
||||
foreach (ResourceAssembly resourceAssembly in resourceAssemblies)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ResourceAssembly resourceAssembly = resourceAssemblies[i];
|
||||
jsonWriter.WriteStartObject(NormalizePath(resourceAssembly.Path));
|
||||
jsonWriter.WriteString(DependencyContextStrings.LocalePropertyName, resourceAssembly.Locale);
|
||||
jsonWriter.WriteEndObject();
|
||||
|
@ -300,33 +302,42 @@ namespace Microsoft.Extensions.DependencyModel
|
|||
|
||||
private static bool AddRuntimeSpecificAssetGroups(string assetType, IEnumerable<RuntimeAssetGroup> assetGroups, bool wroteObjectStart, Utf8JsonWriter jsonWriter)
|
||||
{
|
||||
IEnumerable<RuntimeAssetGroup> groups = assetGroups.Where(g => !string.IsNullOrEmpty(g.Runtime));
|
||||
if (!wroteObjectStart && groups.Any())
|
||||
{
|
||||
jsonWriter.WriteStartObject(DependencyContextStrings.RuntimeTargetsPropertyName);
|
||||
wroteObjectStart = true;
|
||||
}
|
||||
foreach (RuntimeAssetGroup group in groups)
|
||||
{
|
||||
if (group.RuntimeFiles.Any())
|
||||
{
|
||||
AddRuntimeSpecificAssets(group.RuntimeFiles, group.Runtime, assetType, jsonWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a placeholder item
|
||||
// We need to generate a pseudo-path because there could be multiple different asset groups with placeholders
|
||||
// Only the last path segment matters, the rest is basically just a GUID.
|
||||
string pseudoPathFolder = assetType == DependencyContextStrings.RuntimeAssetType ?
|
||||
"lib" :
|
||||
"native";
|
||||
using IEnumerator<RuntimeAssetGroup> groups = assetGroups.Where(g => !string.IsNullOrEmpty(g.Runtime)).GetEnumerator();
|
||||
|
||||
jsonWriter.WriteStartObject($"runtime/{group.Runtime}/{pseudoPathFolder}/_._");
|
||||
jsonWriter.WriteString(DependencyContextStrings.RidPropertyName, group.Runtime);
|
||||
jsonWriter.WriteString(DependencyContextStrings.AssetTypePropertyName, assetType);
|
||||
jsonWriter.WriteEndObject();
|
||||
if (groups.MoveNext())
|
||||
{
|
||||
if (!wroteObjectStart)
|
||||
{
|
||||
jsonWriter.WriteStartObject(DependencyContextStrings.RuntimeTargetsPropertyName);
|
||||
wroteObjectStart = true;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
RuntimeAssetGroup group = groups.Current;
|
||||
|
||||
if (group.RuntimeFiles.Count != 0)
|
||||
{
|
||||
AddRuntimeSpecificAssets(group.RuntimeFiles, group.Runtime, assetType, jsonWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a placeholder item
|
||||
// We need to generate a pseudo-path because there could be multiple different asset groups with placeholders
|
||||
// Only the last path segment matters, the rest is basically just a GUID.
|
||||
string pseudoPathFolder = assetType == DependencyContextStrings.RuntimeAssetType ?
|
||||
"lib" :
|
||||
"native";
|
||||
|
||||
jsonWriter.WriteStartObject($"runtime/{group.Runtime}/{pseudoPathFolder}/_._");
|
||||
jsonWriter.WriteString(DependencyContextStrings.RidPropertyName, group.Runtime);
|
||||
jsonWriter.WriteString(DependencyContextStrings.AssetTypePropertyName, assetType);
|
||||
jsonWriter.WriteEndObject();
|
||||
}
|
||||
}
|
||||
while (groups.MoveNext());
|
||||
}
|
||||
|
||||
return wroteObjectStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,11 +159,11 @@ namespace System.ComponentModel.Composition
|
|||
|
||||
private string BuildDefaultMessage()
|
||||
{
|
||||
IEnumerable<IEnumerable<CompositionError>> paths = CalculatePaths(this);
|
||||
List<Stack<CompositionError>> paths = CalculatePaths(this);
|
||||
|
||||
StringBuilder writer = new StringBuilder();
|
||||
|
||||
WriteHeader(writer, Errors.Count, paths.Count());
|
||||
WriteHeader(writer, Errors.Count, paths.Count);
|
||||
WritePaths(writer, paths);
|
||||
|
||||
return writer.ToString();
|
||||
|
@ -205,30 +205,32 @@ namespace System.ComponentModel.Composition
|
|||
writer.AppendLine(SR.CompositionException_ReviewErrorProperty);
|
||||
}
|
||||
|
||||
private static void WritePaths(StringBuilder writer, IEnumerable<IEnumerable<CompositionError>> paths)
|
||||
private static void WritePaths(StringBuilder writer, List<Stack<CompositionError>> paths)
|
||||
{
|
||||
int ordinal = 0;
|
||||
foreach (IEnumerable<CompositionError> path in paths)
|
||||
foreach (Stack<CompositionError> path in paths)
|
||||
{
|
||||
ordinal++;
|
||||
WritePath(writer, path, ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WritePath(StringBuilder writer, IEnumerable<CompositionError> path, int ordinal)
|
||||
private static void WritePath(StringBuilder writer, Stack<CompositionError> path, int ordinal)
|
||||
{
|
||||
writer.AppendLine();
|
||||
writer.Append(ordinal.ToString(CultureInfo.CurrentCulture));
|
||||
writer.Append(SR.CompositionException_PathsCountSeparator);
|
||||
writer.Append(' ');
|
||||
|
||||
WriteError(writer, path.First());
|
||||
|
||||
foreach (CompositionError error in path.Skip(1))
|
||||
bool needsSeparator = false;
|
||||
foreach (CompositionError error in path)
|
||||
{
|
||||
writer.AppendLine();
|
||||
writer.Append(SR.CompositionException_ErrorPrefix);
|
||||
writer.Append(' ');
|
||||
if (needsSeparator)
|
||||
{
|
||||
writer.AppendLine().Append(SR.CompositionException_ErrorPrefix).Append(' ');
|
||||
}
|
||||
needsSeparator = true;
|
||||
|
||||
WriteError(writer, error);
|
||||
}
|
||||
}
|
||||
|
@ -258,9 +260,9 @@ namespace System.ComponentModel.Composition
|
|||
writer.AppendLine();
|
||||
}
|
||||
|
||||
private static IEnumerable<IEnumerable<CompositionError>> CalculatePaths(CompositionException exception)
|
||||
private static List<Stack<CompositionError>> CalculatePaths(CompositionException exception)
|
||||
{
|
||||
List<IEnumerable<CompositionError>> paths = new List<IEnumerable<CompositionError>>();
|
||||
List<Stack<CompositionError>> paths = new List<Stack<CompositionError>>();
|
||||
|
||||
VisitContext context = default;
|
||||
context.Path = new Stack<CompositionError>();
|
||||
|
|
|
@ -814,7 +814,7 @@ namespace System.ComponentModel.Composition.Hosting
|
|||
|
||||
foreach (var import in definition.ImportDefinitions.Where(ImportEngine.IsRequiredImportForPreview))
|
||||
{
|
||||
if (changedExports.Any(export => import.IsConstraintSatisfiedBy(export)))
|
||||
if (changedExports.Any(import.IsConstraintSatisfiedBy))
|
||||
{
|
||||
affectedRejections.Add(definition);
|
||||
break;
|
||||
|
|
|
@ -203,18 +203,21 @@ namespace System.ComponentModel.Composition.Hosting
|
|||
|
||||
private void InitializeTypeCatalog(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var type in types)
|
||||
Type[] arr = types.ToArray();
|
||||
foreach (Type type in arr)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw ExceptionBuilder.CreateContainsNullElement(nameof(types));
|
||||
}
|
||||
else if (type.Assembly.ReflectionOnly)
|
||||
|
||||
if (type.Assembly.ReflectionOnly)
|
||||
{
|
||||
throw new ArgumentException(SR.Format(SR.Argument_ElementReflectionOnlyType, nameof(types)), nameof(types));
|
||||
}
|
||||
}
|
||||
_types = types.ToArray();
|
||||
|
||||
_types = arr;
|
||||
}
|
||||
|
||||
public override IEnumerator<ComposablePartDefinition> GetEnumerator()
|
||||
|
|
|
@ -496,7 +496,7 @@ namespace System.Composition.Convention
|
|||
|
||||
internal bool BuildConstructorAttributes(Type type, ref List<Tuple<object, List<Attribute>>> configuredMembers)
|
||||
{
|
||||
IEnumerable<ConstructorInfo> constructors = type.GetTypeInfo().DeclaredConstructors;
|
||||
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
|
||||
|
||||
// First see if any of these constructors have the ImportingConstructorAttribute if so then we are already done
|
||||
foreach (ConstructorInfo ci in constructors)
|
||||
|
@ -534,7 +534,7 @@ namespace System.Composition.Convention
|
|||
|
||||
internal static void BuildDefaultConstructorAttributes(Type type, ref List<Tuple<object, List<Attribute>>> configuredMembers)
|
||||
{
|
||||
IEnumerable<ConstructorInfo> constructors = type.GetTypeInfo().DeclaredConstructors;
|
||||
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
|
||||
|
||||
foreach (ConstructorInfo constructorInfo in FindLongestConstructors(constructors))
|
||||
{
|
||||
|
@ -733,7 +733,7 @@ namespace System.Composition.Convention
|
|||
return;
|
||||
}
|
||||
|
||||
private static IEnumerable<ConstructorInfo> FindLongestConstructors(IEnumerable<ConstructorInfo> constructors)
|
||||
private static IEnumerable<ConstructorInfo> FindLongestConstructors(ConstructorInfo[] constructors)
|
||||
{
|
||||
ConstructorInfo longestConstructor = null;
|
||||
int argumentsCount = 0;
|
||||
|
|
|
@ -111,15 +111,15 @@ namespace System.Composition.Hosting.Core
|
|||
CheckTarget(dependency, @checked, checking);
|
||||
}
|
||||
|
||||
private static StringBuilder DescribeCompositionStack(CompositionDependency import, IEnumerable<CompositionDependency> dependencies)
|
||||
private static StringBuilder DescribeCompositionStack(CompositionDependency import, Stack<CompositionDependency> dependencies)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
if (dependencies.FirstOrDefault() == null)
|
||||
if (dependencies.Count == 0 || dependencies.Peek() == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var step in dependencies)
|
||||
foreach (CompositionDependency step in dependencies)
|
||||
{
|
||||
result.AppendFormat(SR.ExportDescriptor_DependencyErrorLine, import.Site, step.Target.Origin);
|
||||
result.AppendLine();
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace System.Data.Common
|
|||
AddEnumerableRange(values, true);
|
||||
}*/
|
||||
|
||||
private void AddEnumerableRange(IEnumerable values, bool doClone)
|
||||
private void AddEnumerableRange(Array values, bool doClone)
|
||||
{
|
||||
if (null == values)
|
||||
{
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace System.Data.Common
|
|||
|
||||
public void AddRange(System.Array values) => AddEnumerableRange(values, false);
|
||||
|
||||
private void AddEnumerableRange(IEnumerable values, bool doClone)
|
||||
private void AddEnumerableRange(Array values, bool doClone)
|
||||
{
|
||||
if (null == values)
|
||||
{
|
||||
|
|
|
@ -150,7 +150,7 @@ namespace System.Data.Odbc
|
|||
return InnerList[index];
|
||||
}
|
||||
|
||||
private static int IndexOf(System.Collections.IEnumerable items, string parameterName)
|
||||
private static int IndexOf(List<OdbcParameter> items, string parameterName)
|
||||
{
|
||||
if (null != items)
|
||||
{
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace System.Data.OleDb
|
|||
return InnerList[index];
|
||||
}
|
||||
|
||||
private static int IndexOf(System.Collections.IEnumerable items, string parameterName)
|
||||
private static int IndexOf(List<OleDbParameter> items, string parameterName)
|
||||
{
|
||||
if (null != items)
|
||||
{
|
||||
|
|
|
@ -38,11 +38,6 @@
|
|||
<type fullname="System.Threading.Timer">
|
||||
<property name="AllTimers" />
|
||||
</type>
|
||||
<type fullname="System.Threading.ThreadPool">
|
||||
<method name="GetQueuedWorkItemsForDebugger" />
|
||||
<method name="GetGloballyQueuedWorkItemsForDebugger" />
|
||||
<method name="GetLocallyQueuedWorkItemsForDebugger" />
|
||||
</type>
|
||||
<type fullname="System.Threading.Tasks.TaskScheduler">
|
||||
<method name="GetScheduledTasksForDebugger" />
|
||||
<method name="GetTaskSchedulersForDebugger" />
|
||||
|
|
|
@ -1450,67 +1450,6 @@ namespace System.Threading
|
|||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<object> GetLocallyQueuedWorkItems()
|
||||
{
|
||||
ThreadPoolWorkQueue.WorkStealingQueue? wsq = ThreadPoolWorkQueueThreadLocals.threadLocals?.workStealingQueue;
|
||||
if (wsq != null && wsq.m_array != null)
|
||||
{
|
||||
object?[] items = wsq.m_array;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
object? item = items[i];
|
||||
if (item != null)
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<object> GetGloballyQueuedWorkItems()
|
||||
{
|
||||
// Enumerate high-priority queue
|
||||
foreach (object workItem in s_workQueue.highPriorityWorkItems)
|
||||
{
|
||||
yield return workItem;
|
||||
}
|
||||
|
||||
// Enumerate global queue
|
||||
foreach (object workItem in s_workQueue.workItems)
|
||||
{
|
||||
yield return workItem;
|
||||
}
|
||||
}
|
||||
|
||||
private static object[] ToObjectArray(IEnumerable<object> workitems)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (object item in workitems)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
object[] result = new object[i];
|
||||
i = 0;
|
||||
foreach (object item in workitems)
|
||||
{
|
||||
if (i < result.Length) // just in case someone calls us while the queues are in motion
|
||||
result[i] = item;
|
||||
i++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is the method the debugger will actually call, if it ends up calling
|
||||
// into ThreadPool directly. Tests can use this to simulate a debugger, as well.
|
||||
internal static object[] GetQueuedWorkItemsForDebugger() =>
|
||||
ToObjectArray(GetQueuedWorkItems());
|
||||
|
||||
internal static object[] GetGloballyQueuedWorkItemsForDebugger() =>
|
||||
ToObjectArray(GetGloballyQueuedWorkItems());
|
||||
|
||||
internal static object[] GetLocallyQueuedWorkItemsForDebugger() =>
|
||||
ToObjectArray(GetLocallyQueuedWorkItems());
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of work items that are currently queued to be processed.
|
||||
/// </summary>
|
||||
|
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
@ -49,15 +48,7 @@ namespace Microsoft.Interop
|
|||
DiagnosticDescriptor descriptor,
|
||||
params object[] args)
|
||||
{
|
||||
IEnumerable<Location> locationsInSource = locations.Where(l => l.IsInSource);
|
||||
if (!locationsInSource.Any())
|
||||
return Diagnostic.Create(descriptor, Location.None, args);
|
||||
|
||||
return Diagnostic.Create(
|
||||
descriptor,
|
||||
location: locationsInSource.First(),
|
||||
additionalLocations: locationsInSource.Skip(1),
|
||||
messageArgs: args);
|
||||
return CreateDiagnostic(locations, descriptor, properties: null, args);
|
||||
}
|
||||
|
||||
public static Diagnostic CreateDiagnostic(
|
||||
|
@ -66,16 +57,26 @@ namespace Microsoft.Interop
|
|||
ImmutableDictionary<string, string> properties,
|
||||
params object[] args)
|
||||
{
|
||||
IEnumerable<Location> locationsInSource = locations.Where(l => l.IsInSource);
|
||||
if (!locationsInSource.Any())
|
||||
return Diagnostic.Create(descriptor, Location.None, args);
|
||||
Location firstLocation = null;
|
||||
List<Location> additionalLocations = null;
|
||||
foreach (Location location in locations)
|
||||
{
|
||||
if (location.IsInSource)
|
||||
{
|
||||
if (firstLocation is null)
|
||||
{
|
||||
firstLocation = location;
|
||||
}
|
||||
else
|
||||
{
|
||||
(additionalLocations ??= new()).Add(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Diagnostic.Create(
|
||||
descriptor,
|
||||
location: locationsInSource.First(),
|
||||
additionalLocations: locationsInSource.Skip(1),
|
||||
properties: properties,
|
||||
messageArgs: args);
|
||||
return firstLocation is null ?
|
||||
Diagnostic.Create(descriptor, Location.None, args) :
|
||||
Diagnostic.Create(descriptor, firstLocation, additionalLocations, properties, args);
|
||||
}
|
||||
|
||||
public static Diagnostic CreateDiagnostic(
|
||||
|
|
Loading…
Reference in New Issue