diff --git a/CliFx.Analyzers/AnalyzerBase.cs b/CliFx.Analyzers/AnalyzerBase.cs index d87615d..3e5aced 100644 --- a/CliFx.Analyzers/AnalyzerBase.cs +++ b/CliFx.Analyzers/AnalyzerBase.cs @@ -28,8 +28,8 @@ public abstract class AnalyzerBase : DiagnosticAnalyzer SupportedDiagnostics = ImmutableArray.Create(SupportedDiagnostic); } - protected Diagnostic CreateDiagnostic(Location location) => - Diagnostic.Create(SupportedDiagnostic, location); + protected Diagnostic CreateDiagnostic(Location location, params object?[]? messageArgs) => + Diagnostic.Create(SupportedDiagnostic, location, messageArgs); public override void Initialize(AnalysisContext context) { diff --git a/CliFx.Analyzers/CommandMustBeAnnotatedAnalyzer.cs b/CliFx.Analyzers/CommandMustBeAnnotatedAnalyzer.cs index 56f5175..67d1697 100644 --- a/CliFx.Analyzers/CommandMustBeAnnotatedAnalyzer.cs +++ b/CliFx.Analyzers/CommandMustBeAnnotatedAnalyzer.cs @@ -41,7 +41,9 @@ public class CommandMustBeAnnotatedAnalyzer : AnalyzerBase // then it's very likely a user error. if (implementsCommandInterface && !hasCommandAttribute) { - context.ReportDiagnostic(CreateDiagnostic(classDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(classDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/CommandMustImplementInterfaceAnalyzer.cs b/CliFx.Analyzers/CommandMustImplementInterfaceAnalyzer.cs index a2710d5..a9e886b 100644 --- a/CliFx.Analyzers/CommandMustImplementInterfaceAnalyzer.cs +++ b/CliFx.Analyzers/CommandMustImplementInterfaceAnalyzer.cs @@ -35,7 +35,9 @@ public class CommandMustImplementInterfaceAnalyzer : AnalyzerBase // it's very likely a user error. if (hasCommandAttribute && !implementsCommandInterface) { - context.ReportDiagnostic(CreateDiagnostic(classDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(classDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/OptionMustBeInsideCommandAnalyzer.cs b/CliFx.Analyzers/OptionMustBeInsideCommandAnalyzer.cs index 7975ba3..805203f 100644 --- a/CliFx.Analyzers/OptionMustBeInsideCommandAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustBeInsideCommandAnalyzer.cs @@ -38,7 +38,9 @@ public class OptionMustBeInsideCommandAnalyzer : AnalyzerBase if (!isInsideCommand) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/OptionMustHaveNameOrShortNameAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveNameOrShortNameAnalyzer.cs index 66c85b2..557c7fa 100644 --- a/CliFx.Analyzers/OptionMustHaveNameOrShortNameAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveNameOrShortNameAnalyzer.cs @@ -27,7 +27,9 @@ public class OptionMustHaveNameOrShortNameAnalyzer : AnalyzerBase if (string.IsNullOrWhiteSpace(option.Name) && option.ShortName is null) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/OptionMustHaveUniqueNameAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveUniqueNameAnalyzer.cs index da17bad..08efe92 100644 --- a/CliFx.Analyzers/OptionMustHaveUniqueNameAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveUniqueNameAnalyzer.cs @@ -14,7 +14,8 @@ public class OptionMustHaveUniqueNameAnalyzer : AnalyzerBase public OptionMustHaveUniqueNameAnalyzer() : base( "Options must have unique names", - "This option's name must be unique within the command (comparison IS NOT case sensitive).") + "This option's name must be unique within the command (comparison IS NOT case sensitive). " + + "Specified name: '{0}'.") { } @@ -51,7 +52,12 @@ public class OptionMustHaveUniqueNameAnalyzer : AnalyzerBase if (string.Equals(option.Name, otherOption.Name, StringComparison.OrdinalIgnoreCase)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + option.Name + ) + ); } } } diff --git a/CliFx.Analyzers/OptionMustHaveUniqueShortNameAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveUniqueShortNameAnalyzer.cs index 1338a99..f271cb5 100644 --- a/CliFx.Analyzers/OptionMustHaveUniqueShortNameAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveUniqueShortNameAnalyzer.cs @@ -13,7 +13,8 @@ public class OptionMustHaveUniqueShortNameAnalyzer : AnalyzerBase public OptionMustHaveUniqueShortNameAnalyzer() : base( "Options must have unique short names", - "This option's short name must be unique within the command (comparison IS case sensitive).") + "This option's short name must be unique within the command (comparison IS case sensitive). " + + "Specified short name: '{0}'.") { } @@ -50,7 +51,12 @@ public class OptionMustHaveUniqueShortNameAnalyzer : AnalyzerBase if (option.ShortName == otherOption.ShortName) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + option.ShortName + ) + ); } } } diff --git a/CliFx.Analyzers/OptionMustHaveValidConverterAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveValidConverterAnalyzer.cs index 835b74a..6fcf08e 100644 --- a/CliFx.Analyzers/OptionMustHaveValidConverterAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveValidConverterAnalyzer.cs @@ -39,7 +39,9 @@ public class OptionMustHaveValidConverterAnalyzer : AnalyzerBase // Value returned by the converter must be assignable to the property type if (converterValueType is null || !property.Type.IsAssignableFrom(converterValueType)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/OptionMustHaveValidNameAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveValidNameAnalyzer.cs index ebec169..a5e2dbe 100644 --- a/CliFx.Analyzers/OptionMustHaveValidNameAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveValidNameAnalyzer.cs @@ -12,7 +12,8 @@ public class OptionMustHaveValidNameAnalyzer : AnalyzerBase public OptionMustHaveValidNameAnalyzer() : base( "Options must have valid names", - "This option's name must be at least 2 characters long and must start with a letter.") + "This option's name must be at least 2 characters long and must start with a letter. " + + "Specified name: '{0}'.") { } @@ -30,7 +31,12 @@ public class OptionMustHaveValidNameAnalyzer : AnalyzerBase if (option.Name.Length < 2 || !char.IsLetter(option.Name[0])) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + option.Name + ) + ); } } diff --git a/CliFx.Analyzers/OptionMustHaveValidShortNameAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveValidShortNameAnalyzer.cs index 2ee58a6..e3b8265 100644 --- a/CliFx.Analyzers/OptionMustHaveValidShortNameAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveValidShortNameAnalyzer.cs @@ -12,7 +12,8 @@ public class OptionMustHaveValidShortNameAnalyzer : AnalyzerBase public OptionMustHaveValidShortNameAnalyzer() : base( "Option short names must be letter characters", - "This option's short name must be a single letter character.") + "This option's short name must be a single letter character. " + + "Specified short name: '{0}'.") { } @@ -30,7 +31,12 @@ public class OptionMustHaveValidShortNameAnalyzer : AnalyzerBase if (!char.IsLetter(option.ShortName.Value)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + option.ShortName + ) + ); } } diff --git a/CliFx.Analyzers/OptionMustHaveValidValidatorsAnalyzer.cs b/CliFx.Analyzers/OptionMustHaveValidValidatorsAnalyzer.cs index d5f7b67..ce0afad 100644 --- a/CliFx.Analyzers/OptionMustHaveValidValidatorsAnalyzer.cs +++ b/CliFx.Analyzers/OptionMustHaveValidValidatorsAnalyzer.cs @@ -37,7 +37,9 @@ public class OptionMustHaveValidValidatorsAnalyzer : AnalyzerBase // Value passed to the validator must be assignable from the property type if (validatorValueType is null || !validatorValueType.IsAssignableFrom(property.Type)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); // No need to report multiple identical diagnostics on the same node break; diff --git a/CliFx.Analyzers/ParameterMustBeInsideCommandAnalyzer.cs b/CliFx.Analyzers/ParameterMustBeInsideCommandAnalyzer.cs index 5cbe96d..6003cfe 100644 --- a/CliFx.Analyzers/ParameterMustBeInsideCommandAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustBeInsideCommandAnalyzer.cs @@ -38,7 +38,9 @@ public class ParameterMustBeInsideCommandAnalyzer : AnalyzerBase if (!isInsideCommand) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/ParameterMustBeLastIfNonRequiredAnalyzer.cs b/CliFx.Analyzers/ParameterMustBeLastIfNonRequiredAnalyzer.cs index 40ff76c..afe96b2 100644 --- a/CliFx.Analyzers/ParameterMustBeLastIfNonRequiredAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustBeLastIfNonRequiredAnalyzer.cs @@ -47,7 +47,9 @@ public class ParameterMustBeLastIfNonRequiredAnalyzer : AnalyzerBase if (otherParameter.Order > parameter.Order) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustBeLastIfNonScalarAnalyzer.cs b/CliFx.Analyzers/ParameterMustBeLastIfNonScalarAnalyzer.cs index ee76e55..f71282a 100644 --- a/CliFx.Analyzers/ParameterMustBeLastIfNonScalarAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustBeLastIfNonScalarAnalyzer.cs @@ -54,7 +54,9 @@ public class ParameterMustBeLastIfNonScalarAnalyzer : AnalyzerBase if (otherParameter.Order > parameter.Order) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustBeSingleIfNonRequiredAnalyzer.cs b/CliFx.Analyzers/ParameterMustBeSingleIfNonRequiredAnalyzer.cs index 6d2886c..73db9bb 100644 --- a/CliFx.Analyzers/ParameterMustBeSingleIfNonRequiredAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustBeSingleIfNonRequiredAnalyzer.cs @@ -47,7 +47,9 @@ public class ParameterMustBeSingleIfNonRequiredAnalyzer : AnalyzerBase if (otherParameter.IsRequired == false) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustBeSingleIfNonScalarAnalyzer.cs b/CliFx.Analyzers/ParameterMustBeSingleIfNonScalarAnalyzer.cs index 7790ff8..5f27252 100644 --- a/CliFx.Analyzers/ParameterMustBeSingleIfNonScalarAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustBeSingleIfNonScalarAnalyzer.cs @@ -52,7 +52,9 @@ public class ParameterMustBeSingleIfNonScalarAnalyzer : AnalyzerBase if (!IsScalar(otherProperty.Type)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustHaveUniqueNameAnalyzer.cs b/CliFx.Analyzers/ParameterMustHaveUniqueNameAnalyzer.cs index f35af33..d7fde82 100644 --- a/CliFx.Analyzers/ParameterMustHaveUniqueNameAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustHaveUniqueNameAnalyzer.cs @@ -14,7 +14,8 @@ public class ParameterMustHaveUniqueNameAnalyzer : AnalyzerBase public ParameterMustHaveUniqueNameAnalyzer() : base( "Parameters must have unique names", - "This parameter's name must be unique within the command (comparison IS NOT case sensitive).") + "This parameter's name must be unique within the command (comparison IS NOT case sensitive). " + + "Specified name: '{0}'.") { } @@ -51,7 +52,12 @@ public class ParameterMustHaveUniqueNameAnalyzer : AnalyzerBase if (string.Equals(parameter.Name, otherParameter.Name, StringComparison.OrdinalIgnoreCase)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + parameter.Name + ) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustHaveUniqueOrderAnalyzer.cs b/CliFx.Analyzers/ParameterMustHaveUniqueOrderAnalyzer.cs index 36cd106..f4ed009 100644 --- a/CliFx.Analyzers/ParameterMustHaveUniqueOrderAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustHaveUniqueOrderAnalyzer.cs @@ -13,7 +13,8 @@ public class ParameterMustHaveUniqueOrderAnalyzer : AnalyzerBase public ParameterMustHaveUniqueOrderAnalyzer() : base( "Parameters must have unique order", - "This parameter's order must be unique within the command.") + "This parameter's order must be unique within the command. " + + "Specified order: {0}.") { } @@ -44,7 +45,12 @@ public class ParameterMustHaveUniqueOrderAnalyzer : AnalyzerBase if (parameter.Order == otherParameter.Order) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic( + propertyDeclaration.Identifier.GetLocation(), + parameter.Order + ) + ); } } } diff --git a/CliFx.Analyzers/ParameterMustHaveValidConverterAnalyzer.cs b/CliFx.Analyzers/ParameterMustHaveValidConverterAnalyzer.cs index 0056310..dc77fea 100644 --- a/CliFx.Analyzers/ParameterMustHaveValidConverterAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustHaveValidConverterAnalyzer.cs @@ -39,7 +39,9 @@ public class ParameterMustHaveValidConverterAnalyzer : AnalyzerBase // Value returned by the converter must be assignable to the property type if (converterValueType is null || !property.Type.IsAssignableFrom(converterValueType)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); } } diff --git a/CliFx.Analyzers/ParameterMustHaveValidValidatorsAnalyzer.cs b/CliFx.Analyzers/ParameterMustHaveValidValidatorsAnalyzer.cs index 6d96595..7311b5f 100644 --- a/CliFx.Analyzers/ParameterMustHaveValidValidatorsAnalyzer.cs +++ b/CliFx.Analyzers/ParameterMustHaveValidValidatorsAnalyzer.cs @@ -37,7 +37,9 @@ public class ParameterMustHaveValidValidatorsAnalyzer : AnalyzerBase // Value passed to the validator must be assignable from the property type if (validatorValueType is null || !validatorValueType.IsAssignableFrom(property.Type)) { - context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(propertyDeclaration.Identifier.GetLocation()) + ); // No need to report multiple identical diagnostics on the same node break; diff --git a/CliFx.Analyzers/SystemConsoleShouldBeAvoidedAnalyzer.cs b/CliFx.Analyzers/SystemConsoleShouldBeAvoidedAnalyzer.cs index ca57ed0..14d7f94 100644 --- a/CliFx.Analyzers/SystemConsoleShouldBeAvoidedAnalyzer.cs +++ b/CliFx.Analyzers/SystemConsoleShouldBeAvoidedAnalyzer.cs @@ -65,7 +65,9 @@ public class SystemConsoleShouldBeAvoidedAnalyzer : AnalyzerBase if (isConsoleInterfaceAvailable) { - context.ReportDiagnostic(CreateDiagnostic(systemConsoleMemberAccess.GetLocation())); + context.ReportDiagnostic( + CreateDiagnostic(systemConsoleMemberAccess.GetLocation()) + ); } }