Improve analyzer diagnostics

This commit is contained in:
Oleksii Holub
2022-04-17 00:01:34 +00:00
committed by GitHub
parent 41cb8647b5
commit ed3e4f471e
21 changed files with 92 additions and 28 deletions

View File

@@ -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)
{

View File

@@ -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())
);
}
}

View File

@@ -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())
);
}
}

View File

@@ -38,7 +38,9 @@ public class OptionMustBeInsideCommandAnalyzer : AnalyzerBase
if (!isInsideCommand)
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}

View File

@@ -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())
);
}
}

View File

@@ -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
)
);
}
}
}

View File

@@ -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
)
);
}
}
}

View File

@@ -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())
);
}
}

View File

@@ -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
)
);
}
}

View File

@@ -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
)
);
}
}

View File

@@ -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;

View File

@@ -38,7 +38,9 @@ public class ParameterMustBeInsideCommandAnalyzer : AnalyzerBase
if (!isInsideCommand)
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}

View File

@@ -47,7 +47,9 @@ public class ParameterMustBeLastIfNonRequiredAnalyzer : AnalyzerBase
if (otherParameter.Order > parameter.Order)
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}
}

View File

@@ -54,7 +54,9 @@ public class ParameterMustBeLastIfNonScalarAnalyzer : AnalyzerBase
if (otherParameter.Order > parameter.Order)
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}
}

View File

@@ -47,7 +47,9 @@ public class ParameterMustBeSingleIfNonRequiredAnalyzer : AnalyzerBase
if (otherParameter.IsRequired == false)
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}
}

View File

@@ -52,7 +52,9 @@ public class ParameterMustBeSingleIfNonScalarAnalyzer : AnalyzerBase
if (!IsScalar(otherProperty.Type))
{
context.ReportDiagnostic(CreateDiagnostic(propertyDeclaration.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(propertyDeclaration.Identifier.GetLocation())
);
}
}
}

View File

@@ -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
)
);
}
}
}

View File

@@ -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
)
);
}
}
}

View File

@@ -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())
);
}
}

View File

@@ -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;

View File

@@ -65,7 +65,9 @@ public class SystemConsoleShouldBeAvoidedAnalyzer : AnalyzerBase
if (isConsoleInterfaceAvailable)
{
context.ReportDiagnostic(CreateDiagnostic(systemConsoleMemberAccess.GetLocation()));
context.ReportDiagnostic(
CreateDiagnostic(systemConsoleMemberAccess.GetLocation())
);
}
}