提交 41d57cd5 编写于 作者: R RoslynTeam

Adjust analyzers for analyers for the current analyzer API. (changeset 1405216)

上级 ef547b73
......@@ -62,7 +62,7 @@ internal class CodeAnalysisDiagnosticsResources {
}
/// <summary>
/// Looks up a localized string similar to Given diagnostic analyzer seems to be marked with a DiagnosticAnalyzerAttribute with a specific supported language. However, the analyzer assembly doesn&apos;t seem to reference any language specific CodeAnalysis assemblies. Hence, it is likely a language-agnostic diagnostic analyzer. Consider either removing the argument to DiagnosticAnalyzerAttribute or adding a new DiagnosticAnalyzerAttribute for missing language..
/// Looks up a localized string similar to Diagnostic analyzer is marked as supporting only one language, but the analyzer assembly doesn&apos;t seem to refer to any language specific CodeAnalysis assemblies, and so is likely to work for more than one language. Consider adding an additional language argument to DiagnosticAnalyzerAttribute..
/// </summary>
internal static string AddLanguageSupportToAnalyzerDescription {
get {
......@@ -71,7 +71,7 @@ internal class CodeAnalysisDiagnosticsResources {
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; seems to be a language-agnostic diagnostic analyzer. Consider either removing the argument to DiagnosticAnalyzerAttribute or adding a new DiagnosticAnalyzerAttribute for &apos;{1}&apos; language support..
/// Looks up a localized string similar to Diagnostic analyzer &apos;{0}&apos; may be able to support both C# and Visual Basic. Consider adding an argument to DiagnosticAnalyzerAttribute for &apos;{1}&apos; language support..
/// </summary>
internal static string AddLanguageSupportToAnalyzerMessage {
get {
......@@ -89,20 +89,20 @@ internal class CodeAnalysisDiagnosticsResources {
}
/// <summary>
/// Looks up a localized string similar to Apply &apos;{0}&apos; DiagnosticAnalyzer attribute..
/// Looks up a localized string similar to Apply DiagnosticAnalyzer attribute for &apos;{0}&apos;..
/// </summary>
internal static string ApplyDiagnosticAnalyzerAttribute_1 {
get {
return ResourceManager.GetString("ApplyDiagnosticAnalyzerAttribute_2", resourceCulture);
return ResourceManager.GetString("ApplyDiagnosticAnalyzerAttribute_1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Apply DiagnosticAnalyzer attributes for both: &apos;{0}&apos; and &apos;{1}&apos;..
/// Looks up a localized string similar to Apply DiagnosticAnalyzer attribute for both &apos;{0}&apos; and &apos;{1}&apos;..
/// </summary>
internal static string ApplyDiagnosticAnalyzerAttribute_2 {
get {
return ResourceManager.GetString("ApplyDiagnosticAnalyzerAttribute_3", resourceCulture);
return ResourceManager.GetString("ApplyDiagnosticAnalyzerAttribute_2", resourceCulture);
}
}
......
......@@ -127,22 +127,19 @@
<value>Non-abstract sub-types of DiagnosticAnalyzer should be marked with DiagnosticAnalyzerAttribute(s). The argument to this attribute(s), if any, determine the supported languages for the analyzer. Analyzer types without this attribute will be ignored by the analysis engine.</value>
</data>
<data name="AddLanguageSupportToAnalyzerMessage" xml:space="preserve">
<value>'{0}' seems to be a language-agnostic diagnostic analyzer. Consider either removing the argument to DiagnosticAnalyzerAttribute or adding a new DiagnosticAnalyzerAttribute for '{1}' language support.</value>
<value>Diagnostic analyzer '{0}' may be able to support both C# and Visual Basic. Consider adding an argument to DiagnosticAnalyzerAttribute for '{1}' language support.</value>
</data>
<data name="AddLanguageSupportToAnalyzerTitle" xml:space="preserve">
<value>Recommend adding language support to diagnostic analyzer.</value>
</data>
<data name="AddLanguageSupportToAnalyzerDescription" xml:space="preserve">
<value>Given diagnostic analyzer seems to be marked with a DiagnosticAnalyzerAttribute with a specific supported language. However, the analyzer assembly doesn't seem to reference any language specific CodeAnalysis assemblies. Hence, it is likely a language-agnostic diagnostic analyzer. Consider either removing the argument to DiagnosticAnalyzerAttribute or adding a new DiagnosticAnalyzerAttribute for missing language.</value>
<value>Diagnostic analyzer is marked as supporting only one language, but the analyzer assembly doesn't seem to refer to any language specific CodeAnalysis assemblies, and so is likely to work for more than one language. Consider adding an additional language argument to DiagnosticAnalyzerAttribute.</value>
</data>
<data name="ApplyDiagnosticAnalyzerAttribute_1" xml:space="preserve">
<value>Apply language-agnostic DiagnosticAnalyzer attribute.</value>
<value>Apply DiagnosticAnalyzer attribute for '{0}'.</value>
</data>
<data name="ApplyDiagnosticAnalyzerAttribute_2" xml:space="preserve">
<value>Apply '{0}' DiagnosticAnalyzer attribute.</value>
</data>
<data name="ApplyDiagnosticAnalyzerAttribute_3" xml:space="preserve">
<value>Apply DiagnosticAnalyzer attributes for both: '{0}' and '{1}'.</value>
<value>Apply DiagnosticAnalyzer attribute for both '{0}' and '{1}'.</value>
</data>
<data name="MissingKindArgumentToRegisterActionMessage" xml:space="preserve">
<value>Specify at least one '{0}' of interest while registering a {1} analyzer action.</value>
......
......@@ -72,31 +72,33 @@ protected override void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext symbolCo
// 2) AddLanguageSupportToAnalyzerRule: For analyzer supporting only one of C# or VB languages, detect if it can support the other language.
var hasAttribute = false;
var hasMultipleAttributes = false;
SyntaxNode attributeSyntax = null;
string supportedLanguage = null;
bool supportsCSharp = false;
bool supportsVB = false;
var namedTypeAttributes = AttributeHelpers.GetApplicableAttributes(namedType);
foreach (var attribute in namedTypeAttributes)
{
if (AttributeHelpers.DerivesFrom(attribute.AttributeClass, DiagnosticAnalyzerAttribute))
{
hasMultipleAttributes |= hasAttribute;
hasAttribute = true;
if (!hasMultipleAttributes)
// The attribute constructor's signature is "(string, params string[])",
// so process both string arguments and string[] arguments.
foreach (TypedConstant arg in attribute.ConstructorArguments)
{
foreach (var arg in attribute.ConstructorArguments)
CheckLanguage(arg, ref supportsCSharp, ref supportsVB);
if (arg.Kind == TypedConstantKind.Array)
{
if (arg.Kind == TypedConstantKind.Primitive &&
arg.Type != null &&
arg.Type.SpecialType == SpecialType.System_String)
foreach (TypedConstant element in arg.Values)
{
supportedLanguage = (string)arg.Value;
attributeSyntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolContext.CancellationToken);
CheckLanguage(element, ref supportsCSharp, ref supportsVB);
}
}
}
attributeSyntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolContext.CancellationToken);
}
}
......@@ -105,28 +107,41 @@ protected override void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext symbolCo
var diagnostic = Diagnostic.Create(MissingDiagnosticAnalyzerAttributeRule, namedType.Locations[0]);
symbolContext.ReportDiagnostic(diagnostic);
}
else if (!hasMultipleAttributes && supportedLanguage != null)
else if (supportsCSharp ^ supportsVB)
{
Debug.Assert(attributeSyntax != null);
var supportsCSharp = supportedLanguage == LanguageNames.CSharp;
var supportsVB = supportedLanguage == LanguageNames.VisualBasic;
if (supportsCSharp || supportsVB)
// If the analyzer assembly doesn't reference either C# or VB CodeAnalysis assemblies,
// then the analyzer is pretty likely a language-agnostic analyzer.
var compilation = symbolContext.Compilation;
var compilationTypeNameToCheck = supportsCSharp ? csharpCompilationFullName : basicCompilationFullName;
var compilationType = compilation.GetTypeByMetadataName(compilationTypeNameToCheck);
if (compilationType == null)
{
// If the analyzer assembly doesn't reference either C# or VB CodeAnalysis assemblies,
// then the analyzer is pretty likely a language-agnostic analyzer.
var compilation = symbolContext.Compilation;
var compilationTypeNameToCheck = supportsCSharp ? csharpCompilationFullName : basicCompilationFullName;
var compilationType = compilation.GetTypeByMetadataName(compilationTypeNameToCheck);
if (compilationType == null)
{
var missingLanguage = supportsCSharp ? LanguageNames.VisualBasic : LanguageNames.CSharp;
var diagnostic = Diagnostic.Create(AddLanguageSupportToAnalyzerRule, attributeSyntax.GetLocation(), namedType.Name, missingLanguage);
symbolContext.ReportDiagnostic(diagnostic);
}
var missingLanguage = supportsCSharp ? LanguageNames.VisualBasic : LanguageNames.CSharp;
var diagnostic = Diagnostic.Create(AddLanguageSupportToAnalyzerRule, attributeSyntax.GetLocation(), namedType.Name, missingLanguage);
symbolContext.ReportDiagnostic(diagnostic);
}
}
}
}
private static void CheckLanguage(TypedConstant argument, ref bool supportsCSharp, ref bool supportsVB)
{
if (argument.Kind == TypedConstantKind.Primitive &&
argument.Type != null &&
argument.Type.SpecialType == SpecialType.System_String)
{
string supportedLanguage = (string)argument.Value;
if (supportedLanguage == LanguageNames.CSharp)
{
supportsCSharp = true;
}
else if (supportedLanguage == LanguageNames.VisualBasic)
{
supportsVB = true;
}
}
}
}
}
......@@ -157,7 +157,6 @@ protected override void AnalyzeNode(SymbolAnalysisContext symbolContext, TInvoca
var isRegisterSymbolAction = IsRegisterAction(RegisterSymbolActionName, method, analysisContext, compilationStartAnalysisContext);
var isRegisterSyntaxNodeAction = IsRegisterAction(RegisterSyntaxNodeActionName, method, analysisContext, compilationStartAnalysisContext, codeBlockStartAnalysisContext);
var isRegisterCodeBlockStartAction = IsRegisterAction(RegisterCodeBlockStartActionName, method, analysisContext, compilationStartAnalysisContext);
var isRegisterCodeBlockEndAction = IsRegisterAction(RegisterCodeBlockEndActionName, method, analysisContext, compilationStartAnalysisContext);
if (isRegisterSymbolAction || isRegisterSyntaxNodeAction)
{
......@@ -211,7 +210,7 @@ protected override void AnalyzeNode(SymbolAnalysisContext symbolContext, TInvoca
}
}
if (isRegisterSyntaxNodeAction || isRegisterCodeBlockStartAction || isRegisterCodeBlockEndAction)
if (isRegisterSyntaxNodeAction || isRegisterCodeBlockStartAction)
{
Debug.Assert(method.TypeParameters.Length > 0);
......
......@@ -19,7 +19,7 @@ public void CSharp_VerifyDiagnostic()
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[DiagnosticAnalyzer(LanguageNames.CSharp, ""MyLanguage"")]
class MyAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
......@@ -52,7 +52,7 @@ Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
<DiagnosticAnalyzer(LanguageNames.VisualBasic, ""MyLanguage"")>
Class MyAnalyzer
Inherits DiagnosticAnalyzer
Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
......@@ -99,9 +99,8 @@ public override void Initialize(AnalysisContext context)
}
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
[DiagnosticAnalyzer(""MyLanguage"")]
class MyAnalyzerWithMultipleAttributes : DiagnosticAnalyzer
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
class MyAnalyzerWithBothLanguages : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
......@@ -147,9 +146,8 @@ End Property
End Sub
End Class
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
<DiagnosticAnalyzer(""MyLanguage"")>
Class MyAnalyzerWithMultipleAttributes
<DiagnosticAnalyzer(LanguageNames.VisualBasic, LanguageNames.CSharp)>
Class MyAnalyzerWithBothLanguages
Inherits DiagnosticAnalyzer
Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
Get
......
......@@ -165,22 +165,6 @@ public void CSharp_NoDiagnosticCases()
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
[DiagnosticAnalyzer]
class MyAnalyzerWithAttribute : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
{
get
{
throw new NotImplementedException();
}
}
public override void Initialize(AnalysisContext context)
{
}
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
class MyAnalyzerWithLanguageSpecificAttribute : DiagnosticAnalyzer
{
......@@ -213,19 +197,6 @@ Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
<DiagnosticAnalyzer>
Class MyAnalyzerWithAttribute
Inherits DiagnosticAnalyzer
Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
Get
Throw New NotImplementedException()
End Get
End Property
Public Overrides Sub Initialize(context As AnalysisContext)
End Sub
End Class
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Class MyAnalyzerWithLanguageSpecificAttribute
Inherits DiagnosticAnalyzer
......
......@@ -21,7 +21,7 @@ public void CSharp_VerifyDiagnostic()
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
[DiagnosticAnalyzer]
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
class MyAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor descriptor =
......@@ -52,7 +52,7 @@ Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
<DiagnosticAnalyzer>
<DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)>
Class MyAnalyzer
Inherits DiagnosticAnalyzer
Private Shared ReadOnly descriptor As DiagnosticDescriptor = new DiagnosticDescriptor(""MyDiagnosticId"", ""MyDiagnosticTitle"", ""MyDiagnosticMessage"", ""MyDiagnosticCategory"", DiagnosticSeverity.Warning, isEnabledByDefault:= true)
......@@ -80,7 +80,7 @@ public void CSharp_NoDiagnosticCases()
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
[DiagnosticAnalyzer]
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
class MyAnalyzer : DiagnosticAnalyzer
{
private static LocalizableString dummyLocalizableTitle = new LocalizableResourceString(""dummyName"", null, null);
......@@ -113,7 +113,7 @@ Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
<DiagnosticAnalyzer>
<DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)>
Class MyAnalyzer
Inherits DiagnosticAnalyzer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册