Skip to content

Commit

Permalink
chore: diagnostics refactoring (#919)
Browse files Browse the repository at this point in the history
  • Loading branch information
latonz authored Nov 20, 2023
1 parent 1724124 commit 1584799
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 31 deletions.
20 changes: 9 additions & 11 deletions src/Riok.Mapperly/Descriptors/DescriptorBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class DescriptorBuilder
private readonly MethodNameBuilder _methodNameBuilder = new();
private readonly MappingBodyBuilder _mappingBodyBuilder;
private readonly SimpleMappingBuilderContext _builderContext;
private readonly List<Diagnostic> _diagnostics = new();
private readonly DiagnosticCollection _diagnostics;
private readonly UnsafeAccessorContext _unsafeAccessorContext;
private readonly MapperConfigurationReader _configurationReader;

Expand All @@ -44,6 +44,7 @@ MapperConfiguration defaultMapperConfiguration

var attributeAccessor = new AttributeDataAccessor(symbolAccessor);
_configurationReader = new MapperConfigurationReader(attributeAccessor, mapperDeclaration.Symbol, defaultMapperConfiguration);
_diagnostics = new DiagnosticCollection(mapperDeclaration.Syntax.GetLocation());

_builderContext = new SimpleMappingBuilderContext(
compilationContext,
Expand All @@ -58,11 +59,12 @@ MapperConfiguration defaultMapperConfiguration
);
}

public (MapperDescriptor descriptor, IReadOnlyCollection<Diagnostic> diagnostics) Build(CancellationToken cancellationToken)
public (MapperDescriptor descriptor, DiagnosticCollection diagnostics) Build(CancellationToken cancellationToken)
{
ConfigureMemberVisibility();
ReserveMethodNames();
ExtractUserMappings();

// ExtractObjectFactories needs to be called after ExtractUserMappings due to configuring mapperDescriptor.Static
var objectFactories = ExtractObjectFactories();
EnqueueUserMappings(objectFactories);
Expand Down Expand Up @@ -93,9 +95,7 @@ private void ConfigureMemberVisibility()
if (includedMembers.HasFlag(MemberVisibility.Accessible))
return;

_diagnostics.Add(
Diagnostic.Create(Diagnostics.DiagnosticDescriptors.UnsafeAccessorNotAvailable, _mapperDescriptor.Syntax.GetLocation())
);
_diagnostics.ReportDiagnostic(DiagnosticDescriptors.UnsafeAccessorNotAvailable);
_symbolAccessor.SetMemberVisibility(includedMembers | MemberVisibility.Accessible);
}

Expand Down Expand Up @@ -131,12 +131,10 @@ private void ExtractUserMappings()

if (_mapperDescriptor.Static && firstNonStaticUserMapping is not null)
{
_diagnostics.Add(
Diagnostic.Create(
DiagnosticDescriptors.MixingStaticPartialWithInstanceMethod,
firstNonStaticUserMapping.Locations.FirstOrDefault(),
_mapperDescriptor.Symbol.ToDisplayString()
)
_diagnostics.ReportDiagnostic(
DiagnosticDescriptors.MixingStaticPartialWithInstanceMethod,
firstNonStaticUserMapping,
_mapperDescriptor.Symbol.ToDisplayString()
);
}
}
Expand Down
23 changes: 5 additions & 18 deletions src/Riok.Mapperly/Descriptors/SimpleMappingBuilderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Riok.Mapperly.Abstractions;
using Riok.Mapperly.Configuration;
using Riok.Mapperly.Descriptors.MappingBuilders;
using Riok.Mapperly.Diagnostics;
using Riok.Mapperly.Symbols;

namespace Riok.Mapperly.Descriptors;
Expand All @@ -12,7 +13,7 @@ namespace Riok.Mapperly.Descriptors;
public class SimpleMappingBuilderContext
{
private readonly MapperDescriptor _descriptor;
private readonly List<Diagnostic> _diagnostics;
private readonly DiagnosticCollection _diagnostics;
private readonly CompilationContext _compilationContext;
private readonly MapperConfigurationReader _configurationReader;

Expand All @@ -23,7 +24,7 @@ public SimpleMappingBuilderContext(
AttributeDataAccessor attributeAccessor,
MapperDescriptor descriptor,
UnsafeAccessorContext unsafeAccessorContext,
List<Diagnostic> diagnostics,
DiagnosticCollection diagnostics,
MappingBuilder mappingBuilder,
ExistingTargetMappingBuilder existingTargetMappingBuilder
)
Expand Down Expand Up @@ -73,22 +74,8 @@ protected SimpleMappingBuilderContext(SimpleMappingBuilderContext ctx)
public virtual bool IsConversionEnabled(MappingConversionType conversionType) =>
MapperConfiguration.EnabledConversions.HasFlag(conversionType);

public void ReportDiagnostic(DiagnosticDescriptor descriptor, ISymbol? location, params object[] messageArgs)
{
// cannot use the symbol since it would break the incremental generator
// due to being different for each compilation.
for (var i = 0; i < messageArgs.Length; i++)
{
if (messageArgs[i] is ISymbol symbol)
{
messageArgs[i] = symbol.ToDisplayString();
}
}

var syntaxNode = location?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax();
var nodeLocation = syntaxNode?.GetLocation();
_diagnostics.Add(Diagnostic.Create(descriptor, nodeLocation ?? _descriptor.Syntax.GetLocation(), messageArgs));
}
public void ReportDiagnostic(DiagnosticDescriptor descriptor, ISymbol? location, params object[] messageArgs) =>
_diagnostics.ReportDiagnostic(descriptor, location, messageArgs);

protected MappingConfiguration ReadConfiguration(MappingConfigurationReference configRef) => _configurationReader.BuildFor(configRef);
}
38 changes: 38 additions & 0 deletions src/Riok.Mapperly/Diagnostics/DiagnosticCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections;
using Microsoft.CodeAnalysis;

namespace Riok.Mapperly.Diagnostics;

public class DiagnosticCollection : IReadOnlyCollection<Diagnostic>
{
private readonly List<Diagnostic> _diagnostics = new();
private readonly Location _defaultLocation;

internal DiagnosticCollection(Location defaultLocation)
{
_defaultLocation = defaultLocation;
}

public IEnumerator<Diagnostic> GetEnumerator() => _diagnostics.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public int Count => _diagnostics.Count;

internal void ReportDiagnostic(DiagnosticDescriptor descriptor, ISymbol? location = null, params object[] messageArgs)
{
// cannot use the symbol since it would break the incremental generator
// due to being different for each compilation.
for (var i = 0; i < messageArgs.Length; i++)
{
if (messageArgs[i] is ISymbol symbol)
{
messageArgs[i] = symbol.ToDisplayString();
}
}

var syntaxNode = location?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax();
var nodeLocation = syntaxNode?.GetLocation();
_diagnostics.Add(Diagnostic.Create(descriptor, nodeLocation ?? _defaultLocation, messageArgs));
}
}
4 changes: 2 additions & 2 deletions src/Riok.Mapperly/MapperGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ CancellationToken cancellationToken
try
{
var builder = new DescriptorBuilder(compilationContext, mapperDeclaration, symbolAccessor, mapperDefaults);
var (descriptor, descriptorDiagnostics) = builder.Build(cancellationToken);
var (descriptor, diagnostics) = builder.Build(cancellationToken);
var mapper = new MapperNode(
compilationContext.FileNameBuilder.Build(descriptor),
SourceEmitter.Build(descriptor, cancellationToken)
);
return new MapperAndDiagnostics(mapper, descriptorDiagnostics.ToImmutableEquatableArray(), descriptor.RequiredTemplates);
return new MapperAndDiagnostics(mapper, diagnostics.ToImmutableEquatableArray(), descriptor.RequiredTemplates);
}
catch (OperationCanceledException)
{
Expand Down

0 comments on commit 1584799

Please sign in to comment.