提交 a9051d3d 编写于 作者: S Srivatsn Narayanan

Move CA1019 (DefineAccessorsForAttributeArguments) to System.Runtime.Analyzers.

上级 b79ace13
......@@ -77,7 +77,6 @@
<Compile Include="Design\CodeFixes\CA1052CSharpCodeFixProvider.cs" />
<Compile Include="Design\CodeFixes\EnumWithFlagsCSharpCodeFixProvider.cs" />
<Compile Include="Design\CSharpCA1003DiagnosticAnalyzer.cs" />
<Compile Include="Design\CSharpCA1019DiagnosticAnalyzer.cs" />
<Compile Include="Design\CSharpCA1024DiagnosticAnalyzer.cs" />
<Compile Include="Design\CSharpEnumWithFlagsDiagnosticAnalyzer.cs" />
<Compile Include="Globalization\CodeFixes\CA1309CSharpCodeFixProvider.cs" />
......
......@@ -107,7 +107,6 @@
<Compile Include="Design\CA1008DiagnosticAnalyzer.cs" />
<Compile Include="Design\CA1012DiagnosticAnalyzer.cs" />
<Compile Include="Design\CA1017DiagnosticAnalyzer.cs" />
<Compile Include="Design\CA1019DiagnosticAnalyzer.cs" />
<Compile Include="Design\CA1024DiagnosticAnalyzer.cs" />
<Compile Include="Design\CA1060DiagnosticAnalyzer.cs" />
<Compile Include="Design\CodeFixes\CA1008CodeFixProviderBase.cs" />
......
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.35317
// Runtime Version:4.0.30319.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
......@@ -204,42 +204,6 @@ internal class FxCopRulesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Define accessors for attribute arguments..
/// </summary>
internal static string DefineAccessorsForAttributeArguments {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArguments", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add a public read-only property accessor for positional argument &apos;{0}&apos; of attribute &apos;{1}&apos;..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsDefault {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsDefault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to If &apos;{0}&apos; is the property accessor for positional argument &apos;{1}&apos;, ensure that property getter is public..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsIncreaseVisibility {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsIncreaseVisibility", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remove the property setter from &apos;{0}&apos; or reduce its accessibility because it corresponds to positional argument &apos;{1}&apos;..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsRemoveSetter {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsRemoveSetter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disposable fields should be disposed.
/// </summary>
......
......@@ -192,15 +192,6 @@
<data name="ChangeToAPropertyIfAppropriate" xml:space="preserve">
<value>Change '{0}' to a property if appropriate.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsDefault" xml:space="preserve">
<value>Add a public read-only property accessor for positional argument '{0}' of attribute '{1}'.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsRemoveSetter" xml:space="preserve">
<value>Remove the property setter from '{0}' or reduce its accessibility because it corresponds to positional argument '{1}'.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsIncreaseVisibility" xml:space="preserve">
<value>If '{0}' is the property accessor for positional argument '{1}', ensure that property getter is public.</value>
</data>
<data name="MarkEnumsWithFlagsMessage" xml:space="preserve">
<value>The constituent members of '{0}' appear to represent flags that can be combined rather than discrete values. If this is correct, mark the enumeration with FlagsAttribute.</value>
</data>
......@@ -228,9 +219,6 @@
<data name="CustomAttrShouldHaveAttributeUsage" xml:space="preserve">
<value>Custom attributes should have AttributeUsage attribute defined.</value>
</data>
<data name="DefineAccessorsForAttributeArguments" xml:space="preserve">
<value>Define accessors for attribute arguments.</value>
</data>
<data name="DoNotLockOnObjectsWithWeakIdentity" xml:space="preserve">
<value>Do not lock on objects with weak identity.</value>
</data>
......
......@@ -71,8 +71,9 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="Design\" />
<Compile Include="Design\DefineAccessorsForAttributeArguments.cs" />
</ItemGroup>
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Imports.targets" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.FxCopAnalyzers.Design;
namespace Microsoft.CodeAnalysis.CSharp.FxCopAnalyzers.Design
namespace System.Runtime.Analyzers
{
/// <summary>
/// CA1019: Define accessors for attribute arguments
......@@ -12,7 +13,7 @@ namespace Microsoft.CodeAnalysis.CSharp.FxCopAnalyzers.Design
/// In its constructor, an attribute defines arguments that do not have corresponding properties.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class CSharpCA1019DiagnosticAnalyzer : CA1019DiagnosticAnalyzer
public class CSharpDefineAccessorsForAttributeArgumentsAnalyzer : DefineAccessorsForAttributeArgumentsAnalyzer
{
protected override bool IsAssignableTo(ITypeSymbol fromSymbol, ITypeSymbol toSymbol, Compilation compilation)
{
......
......@@ -5,10 +5,10 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities;
namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design
namespace System.Runtime.Analyzers
{
/// <summary>
/// CA1019: Define accessors for attribute arguments
......@@ -16,19 +16,19 @@ namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design
/// Cause:
/// In its constructor, an attribute defines arguments that do not have corresponding properties.
/// </summary>
public abstract class CA1019DiagnosticAnalyzer : AbstractNamedTypeAnalyzer
public abstract class DefineAccessorsForAttributeArgumentsAnalyzer : DiagnosticAnalyzer
{
internal const string RuleId = "CA1019";
private static LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(FxCopRulesResources.DefineAccessorsForAttributeArguments), FxCopRulesResources.ResourceManager, typeof(FxCopRulesResources));
private static LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArguments), SystemRuntimeAnalyzersResources.ResourceManager, typeof(SystemRuntimeAnalyzersResources));
internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(RuleId,
s_localizableTitle,
"{0}",
FxCopDiagnosticCategory.Design,
DiagnosticCategory.Design,
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
helpLinkUri: "http://msdn.microsoft.com/library/ms182136.aspx",
customTags: DiagnosticCustomTags.Microsoft);
customTags: WellKnownDiagnosticTags.Telemetry);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
......@@ -38,9 +38,18 @@ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
}
}
protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
public override void Initialize(AnalysisContext analysisContext)
{
if (symbol != null && symbol.IsAttribute() && symbol.DeclaredAccessibility != Accessibility.Private)
analysisContext.RegisterSymbolAction(context =>
{
AnalyzeSymbol((INamedTypeSymbol)context.Symbol, context.Compilation, context.ReportDiagnostic, context.Options, context.CancellationToken);
},
SymbolKind.NamedType);
}
private void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action<Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken)
{
if (symbol != null && symbol.GetBaseTypesAndThis().Contains(WellKnownTypes.Attribute(compilation)) && symbol.DeclaredAccessibility != Accessibility.Private)
{
IEnumerable<IParameterSymbol> parametersToCheck = GetAllPublicConstructorParameters(symbol);
if (parametersToCheck.Any())
......@@ -98,7 +107,7 @@ private void AnalyzeParameters(Compilation compilation, IEnumerable<IParameterSy
{
foreach (var parameter in parameters)
{
if (!parameter.Type.IsErrorType())
if (parameter.Type.Kind != SymbolKind.ErrorType)
{
IPropertySymbol property;
if (!propertiesMap.TryGetValue(parameter.Name, out property) ||
......@@ -148,21 +157,21 @@ private void AnalyzeParameters(Compilation compilation, IEnumerable<IParameterSy
private static Diagnostic GetDefaultDiagnostic(IParameterSymbol parameter, INamedTypeSymbol attributeType)
{
// Add a public read-only property accessor for positional argument '{0}' of attribute '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsDefault, parameter.Name, attributeType.Name);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsDefault, parameter.Name, attributeType.Name);
return parameter.CreateDiagnostic(Rule, message);
}
private static Diagnostic GetIncreaseVisibilityDiagnostic(IParameterSymbol parameter, IPropertySymbol property)
{
// If '{0}' is the property accessor for positional argument '{1}', make it public.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, property.Name, parameter.Name);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, property.Name, parameter.Name);
return property.GetMethod.CreateDiagnostic(Rule, message);
}
private static Diagnostic GetRemoveSetterDiagnostic(IParameterSymbol parameter, IPropertySymbol property)
{
// Remove the property setter from '{0}' or reduce its accessibility because it corresponds to positional argument '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsRemoveSetter, property.Name, parameter.Name);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsRemoveSetter, property.Name, parameter.Name);
return property.SetMethod.CreateDiagnostic(Rule, message);
}
}
......
......@@ -53,7 +53,7 @@ private static void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilati
return;
}
if (symbol.IsAbstract || !symbol.GetBaseTypes().Contains(WellKnownTypes.Attribute(compilation)))
if (symbol.IsAbstract || !symbol.GetBaseTypesAndThis().Contains(WellKnownTypes.Attribute(compilation)))
{
return;
}
......
using System.Collections.Generic;
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
namespace System.Runtime.Analyzers
{
internal static class INamedTypeSymbolExtensions
{
public static IEnumerable<INamedTypeSymbol> GetBaseTypes(this ITypeSymbol type)
public static IEnumerable<INamedTypeSymbol> GetBaseTypesAndThis(this INamedTypeSymbol type)
{
var current = type.BaseType;
var current = type;
while (current != null)
{
yield return current;
......
......@@ -53,6 +53,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Design\DefineAccessorsForAttributeArguments.cs" />
<Compile Include="Design\MarkAttributesWithAttributeUsage.cs" />
<Compile Include="Design\TypesThatOwnDisposableFieldsShouldBeDisposable.Fixer.cs" />
<Compile Include="Design\TypesThatOwnDisposableFieldsShouldBeDisposable.cs" />
......
......@@ -133,6 +133,42 @@ internal class SystemRuntimeAnalyzersResources {
}
}
/// <summary>
/// Looks up a localized string similar to Define accessors for attribute arguments..
/// </summary>
internal static string DefineAccessorsForAttributeArguments {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArguments", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add a public read-only property accessor for positional argument &apos;{0}&apos; of attribute &apos;{1}&apos;..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsDefault {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsDefault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to If &apos;{0}&apos; is the property accessor for positional argument &apos;{1}&apos;, ensure that property getter is public..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsIncreaseVisibility {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsIncreaseVisibility", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remove the property setter from &apos;{0}&apos; or reduce its accessibility because it corresponds to positional argument &apos;{1}&apos;..
/// </summary>
internal static string DefineAccessorsForAttributeArgumentsRemoveSetter {
get {
return ResourceManager.GetString("DefineAccessorsForAttributeArgumentsRemoveSetter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Implement IDisposable Interface.
/// </summary>
......
......@@ -153,4 +153,16 @@
<data name="MarkAttributesWithAttributeUsage" xml:space="preserve">
<value>Specify AttributeUsage attribute on '{0}' attribute class.</value>
</data>
<data name="DefineAccessorsForAttributeArguments" xml:space="preserve">
<value>Define accessors for attribute arguments.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsDefault" xml:space="preserve">
<value>Add a public read-only property accessor for positional argument '{0}' of attribute '{1}'.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsIncreaseVisibility" xml:space="preserve">
<value>If '{0}' is the property accessor for positional argument '{1}', ensure that property getter is public.</value>
</data>
<data name="DefineAccessorsForAttributeArgumentsRemoveSetter" xml:space="preserve">
<value>Remove the property setter from '{0}' or reduce its accessibility because it corresponds to positional argument '{1}'.</value>
</data>
</root>
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.FxCopAnalyzers.Design;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.FxCopAnalyzers;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Design;
using Roslyn.Test.Utilities;
using Microsoft.CodeAnalysis.UnitTests;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests
namespace System.Runtime.Analyzers.UnitTests
{
public partial class CA1019Tests : DiagnosticAnalyzerTestBase
public partial class DefineAccessorsForAttributeArgumentsTests : DiagnosticAnalyzerTestBase
{
protected override DiagnosticAnalyzer GetBasicDiagnosticAnalyzer()
{
return new BasicCA1019DiagnosticAnalyzer();
return new BasicDefineAccessorsForAttributeArgumentsAnalyzer();
}
protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
{
return new CSharpCA1019DiagnosticAnalyzer();
return new CSharpDefineAccessorsForAttributeArgumentsAnalyzer();
}
#region No Diagnostic Tests
......@@ -2761,42 +2758,42 @@ End Class
private static DiagnosticResult GetCA1019CSharpDefaultResultAt(int line, int column, string paramName, string attributeTypeName)
{
// Add a public read-only property accessor for positional argument '{0}' of attribute '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsDefault, paramName, attributeTypeName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsDefault, paramName, attributeTypeName);
return GetCSharpResultAt(line, column, CA1019Name, message);
}
private static DiagnosticResult GetCA1019BasicDefaultResultAt(int line, int column, string paramName, string attributeTypeName)
{
// Add a public read-only property accessor for positional argument '{0}' of attribute '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsDefault, paramName, attributeTypeName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsDefault, paramName, attributeTypeName);
return GetBasicResultAt(line, column, CA1019Name, message);
}
private static DiagnosticResult GetCA1019CSharpIncreaseVisibilityResultAt(int line, int column, string propertyName, string paramName)
{
// If '{0}' is the property accessor for positional argument '{1}', make it public.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, propertyName, paramName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, propertyName, paramName);
return GetCSharpResultAt(line, column, CA1019Name, message);
}
private static DiagnosticResult GetCA1019BasicIncreaseVisibilityResultAt(int line, int column, string propertyName, string paramName)
{
// If '{0}' is the property accessor for positional argument '{1}', make it public.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, propertyName, paramName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsIncreaseVisibility, propertyName, paramName);
return GetBasicResultAt(line, column, CA1019Name, message);
}
private static DiagnosticResult GetCA1019CSharpRemoveSetterResultAt(int line, int column, string propertyName, string paramName)
{
// Remove the property setter from '{0}' or reduce its accessibility because it corresponds to positional argument '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsRemoveSetter, propertyName, paramName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsRemoveSetter, propertyName, paramName);
return GetCSharpResultAt(line, column, CA1019Name, message);
}
private static DiagnosticResult GetCA1019BasicRemoveSetterResultAt(int line, int column, string propertyName, string paramName)
{
// Remove the property setter from '{0}' or reduce its accessibility because it corresponds to positional argument '{1}'.
var message = string.Format(FxCopRulesResources.DefineAccessorsForAttributeArgumentsRemoveSetter, propertyName, paramName);
var message = string.Format(SystemRuntimeAnalyzersResources.DefineAccessorsForAttributeArgumentsRemoveSetter, propertyName, paramName);
return GetBasicResultAt(line, column, CA1019Name, message);
}
}
......
......@@ -97,6 +97,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Design\DefineAccessorsForAttributeArgumentsTests.cs" />
<Compile Include="Design\MarkAttributesWithAttributeUsageTests.cs" />
<Compile Include="Design\TypesThatOwnDisposableFieldsShouldBeDisposableTests.Fixer.cs" />
<Compile Include="Design\TypesThatOwnDisposableFieldsShouldBeDisposableTests.cs" />
......
......@@ -70,10 +70,12 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Compile Include="Design\DefineAccessorsForAttributeArguments.vb" />
</ItemGroup>
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.FxCopAnalyzers.Design
Imports Microsoft.CodeAnalysis.VisualBasic
Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Design
Namespace System.Runtime.Analyzers
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Public Class BasicCA1019DiagnosticAnalyzer
Inherits CA1019DiagnosticAnalyzer
Public Class BasicDefineAccessorsForAttributeArgumentsAnalyzer
Inherits DefineAccessorsForAttributeArgumentsAnalyzer
Protected Overrides Function IsAssignableTo(fromSymbol As ITypeSymbol, toSymbol As ITypeSymbol, compilation As Compilation) As Boolean
Return fromSymbol IsNot Nothing AndAlso toSymbol IsNot Nothing AndAlso DirectCast(compilation, VisualBasicCompilation).ClassifyConversion(fromSymbol, toSymbol).IsWidening
......
......@@ -86,7 +86,6 @@
<Compile Include="Design\CA1014Tests.cs" />
<Compile Include="Design\CA1016Tests.cs" />
<Compile Include="Design\CA1017Tests.cs" />
<Compile Include="Design\CA1019Tests.cs" />
<Compile Include="Design\CA1024Tests.cs" />
<Compile Include="Design\CA1052Tests.cs" />
<Compile Include="Design\CA1053Tests.cs" />
......
......@@ -96,7 +96,6 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Design\BasicCA1003DiagnosticAnalyzer.vb" />
<Compile Include="Design\BasicCA1019DiagnosticAnalyzer.vb" />
<Compile Include="Design\BasicCA1024DiagnosticAnalyzer.vb" />
<Compile Include="Design\BasicEnumWithFlagsDiagnosticAnalyzer.vb" />
<Compile Include="Design\CodeFixes\CA1008BasicCodeFixProvider.vb" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册