Issue diagnostics when encountering errors.

This commit is contained in:
Alexandru Macocian
2021-04-06 17:03:42 +02:00
parent 41fb97f7b7
commit 6a6e26462b
3 changed files with 67 additions and 10 deletions
@@ -60,6 +60,7 @@ namespace System.Extensions
var attributeSymbol = compilation.GetTypeByMetadataName($"{AttributeNamespace}.{AttributeName}");
if (attributeSymbol is null)
{
context.ReportDiagnostic(Diagnostics.MissingAttributeDiagnostic(AttributeName, AttributeNamespace));
return;
}
@@ -79,16 +80,21 @@ namespace System.Extensions
foreach (var group in fieldSymbols.GroupBy(f => f.ContainingType, SymbolEqualityComparer.IncludeNullability))
{
var classSource = ProcessClass((INamedTypeSymbol)group.Key, attributeSymbol, group.ToList());
var classSource = ProcessClass((INamedTypeSymbol)group.Key, attributeSymbol, group.ToList(), context);
context.ReportDiagnostic(Diagnostics.GeneratedSymbolsForClassDiagnostic(group.Key.Name));
context.AddSource($"{group.Key.Name}.DependencyPropertyGenerator.g.cs", classSource);
}
}
private static string ProcessClass(INamedTypeSymbol classSymbol, INamedTypeSymbol attributeSymbol, List<IFieldSymbol> fields)
private static string ProcessClass(INamedTypeSymbol classSymbol, INamedTypeSymbol attributeSymbol, List<IFieldSymbol> fields, GeneratorExecutionContext generatorExecutionContext)
{
if (!classSymbol.ContainingSymbol.Equals(classSymbol.ContainingNamespace, SymbolEqualityComparer.Default))
{
return null; //TODO: issue a diagnostic that it must be top level
var syntaxTree = classSymbol.DeclaringSyntaxReferences.First().SyntaxTree;
var textSpan = classSymbol.DeclaringSyntaxReferences.First().Span;
generatorExecutionContext.ReportDiagnostic(
Diagnostics.ClassNotTopLevelDiagnostic(classSymbol.Name, classSymbol.ContainingSymbol.Name, syntaxTree, textSpan));
return null;
}
var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
@@ -127,11 +133,6 @@ namespace System.Extensions
var fieldType = fieldSymbol.Type;
string propertyName = GenerateName(fieldName);
if (propertyName.Length == 0 || propertyName == fieldName)
{
//TODO: issue a diagnostic that we can't process this field
return;
}
var attributeData = fieldSymbol.GetAttributes().Single(ad => ad.AttributeClass.Equals(attributeSymbol, SymbolEqualityComparer.Default));
var initialValueOpt = attributeData.NamedArguments.SingleOrDefault(kvp => kvp.Key == "InitialValue").Value;
@@ -0,0 +1,51 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
namespace System.Extensions
{
internal static class Diagnostics
{
public const string DependencyPropertyGenerator_NoAttributeFound = "DGD 0001";
public const string DependencyPropertyGenerator_ClassMustBeTopLevel = "DGD 1001";
public const string DependencyPropertyGenerator_Success = "DGD 3001";
public static Diagnostic MissingAttributeDiagnostic(string attributeName, string attributeNamespace) => Diagnostic.Create(
new DiagnosticDescriptor(
DependencyPropertyGenerator_NoAttributeFound,
$"{attributeNamespace}.{attributeName} not found",
"Could not find attribute with name {0} in namespace {1}.",
"WpfExtended.SourceGeneration",
DiagnosticSeverity.Error,
true,
$"This error occurs when the attribute generated by the {nameof(DependencyPropertyGenerator)} is not found",
null),
Location.None,
attributeName, attributeNamespace);
public static Diagnostic ClassNotTopLevelDiagnostic(string className, string containingSymbol, SyntaxTree syntaxTree, TextSpan textSpan) => Diagnostic.Create(
new DiagnosticDescriptor(
DependencyPropertyGenerator_ClassMustBeTopLevel,
$"{className} must be top level",
"Class {0} must be top level. It is currently declared under {1}.",
"WpfExtended.SourceGeneration",
DiagnosticSeverity.Error,
true,
null,
null),
Location.Create(syntaxTree, textSpan),
className, containingSymbol);
public static Diagnostic GeneratedSymbolsForClassDiagnostic(string className) => Diagnostic.Create(
new DiagnosticDescriptor(
DependencyPropertyGenerator_Success,
$"{className} created dependency properties",
"DependencyPropertyGenerator successfully created implementations for properties in {0}",
"WpfExtended.SourceGeneration",
DiagnosticSeverity.Info,
true,
null,
null),
Location.None,
className);
}
}
@@ -7,7 +7,7 @@
<Authors>Alexandru Macocian</Authors>
<Description>Source generator library.</Description>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>0.1</Version>
<Version>0.1.1</Version>
<LangVersion>latest</LangVersion>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>
@@ -25,5 +25,10 @@
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<!-- Package the generator in the analyzer directory of the nuget package -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Project>