Skip to content

Commit d6bc11f

Browse files
committed
Port DiagnosticInfo from ComputeSharp
1 parent eb09343 commit d6bc11f

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

CommunityToolkit.Mvvm.SourceGenerators/CommunityToolkit.Mvvm.SourceGenerators.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<Compile Include="$(MSBuildThisFileDirectory)Messaging\IMessengerRegisterAllGenerator.cs" />
7878
<Compile Include="$(MSBuildThisFileDirectory)Messaging\IMessengerRegisterAllGenerator.Execute.cs" />
7979
<Compile Include="$(MSBuildThisFileDirectory)Messaging\Models\RecipientInfo.cs" />
80+
<Compile Include="$(MSBuildThisFileDirectory)Models\DiagnosticInfo.cs" />
8081
<Compile Include="$(MSBuildThisFileDirectory)Models\HierarchyInfo.cs" />
8182
<Compile Include="$(MSBuildThisFileDirectory)Models\HierarchyInfo.Syntax.cs" />
8283
<Compile Include="$(MSBuildThisFileDirectory)Models\Result.cs" />
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
6+
// more info in ThirdPartyNotices.txt in the root of the project.
7+
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Collections.Immutable;
11+
using System.Linq;
12+
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
13+
using CommunityToolkit.Mvvm.SourceGenerators.Helpers;
14+
using Microsoft.CodeAnalysis;
15+
using Microsoft.CodeAnalysis.Text;
16+
17+
namespace CommunityToolkit.Mvvm.SourceGenerators.Models;
18+
19+
/// <summary>
20+
/// A model for a serializeable diagnostic info.
21+
/// </summary>
22+
/// <param name="Descriptor">The wrapped <see cref="DiagnosticDescriptor"/> instance.</param>
23+
/// <param name="SyntaxTree">The tree to use as location for the diagnostic, if available.</param>
24+
/// <param name="TextSpan">The span to use as location for the diagnostic.</param>
25+
/// <param name="Arguments">The diagnostic arguments.</param>
26+
internal sealed record DiagnosticInfo(
27+
DiagnosticDescriptor Descriptor,
28+
SyntaxTree? SyntaxTree,
29+
TextSpan TextSpan,
30+
ImmutableArray<string> Arguments)
31+
{
32+
/// <inheritdoc/>
33+
public bool Equals(DiagnosticInfo? obj) => Comparer.Default.Equals(this, obj);
34+
35+
/// <inheritdoc/>
36+
public override int GetHashCode() => Comparer.Default.GetHashCode(this);
37+
38+
/// <summary>
39+
/// Creates a new <see cref="Diagnostic"/> instance with the state from this model.
40+
/// </summary>
41+
/// <returns>A new <see cref="Diagnostic"/> instance with the state from this model.</returns>
42+
public Diagnostic ToDiagnostic()
43+
{
44+
if (SyntaxTree is not null)
45+
{
46+
return Diagnostic.Create(Descriptor, Location.Create(SyntaxTree, TextSpan), Arguments.ToArray());
47+
}
48+
49+
return Diagnostic.Create(Descriptor, null, Arguments.ToArray());
50+
}
51+
52+
/// <summary>
53+
/// Creates a new <see cref="DiagnosticInfo"/> instance with the specified parameters.
54+
/// </summary>
55+
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
56+
/// <param name="symbol">The source <see cref="ISymbol"/> to attach the diagnostics to.</param>
57+
/// <param name="args">The optional arguments for the formatted message to include.</param>
58+
/// <returns>A new <see cref="DiagnosticInfo"/> instance with the specified parameters.</returns>
59+
public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, ISymbol symbol, params object[] args)
60+
{
61+
Location location = symbol.Locations.First();
62+
63+
return new(descriptor, location.SourceTree, location.SourceSpan, args.Select(static arg => arg.ToString()).ToImmutableArray());
64+
}
65+
66+
/// <summary>
67+
/// Creates a new <see cref="DiagnosticInfo"/> instance with the specified parameters.
68+
/// </summary>
69+
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
70+
/// <param name="node">The source <see cref="SyntaxNode"/> to attach the diagnostics to.</param>
71+
/// <param name="args">The optional arguments for the formatted message to include.</param>
72+
/// <returns>A new <see cref="DiagnosticInfo"/> instance with the specified parameters.</returns>
73+
public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, SyntaxNode node, params object[] args)
74+
{
75+
Location location = node.GetLocation();
76+
77+
return new(descriptor, location.SourceTree, location.SourceSpan, args.Select(static arg => arg.ToString()).ToImmutableArray());
78+
}
79+
80+
/// <summary>
81+
/// An <see cref="IEqualityComparer{T}"/> implementation for <see cref="DiagnosticInfo"/>.
82+
/// </summary>
83+
private sealed class Comparer : Comparer<DiagnosticInfo, Comparer>
84+
{
85+
/// <inheritdoc/>
86+
protected override void AddToHashCode(ref HashCode hashCode, DiagnosticInfo obj)
87+
{
88+
hashCode.Add(obj.Descriptor);
89+
hashCode.Add(obj.SyntaxTree);
90+
hashCode.Add(obj.TextSpan);
91+
hashCode.AddRange(obj.Arguments);
92+
}
93+
94+
/// <inheritdoc/>
95+
protected override bool AreEqual(DiagnosticInfo x, DiagnosticInfo y)
96+
{
97+
return
98+
x.Descriptor.Equals(y.Descriptor) &&
99+
x.SyntaxTree == y.SyntaxTree &&
100+
x.TextSpan.Equals(y.TextSpan) &&
101+
x.Arguments.SequenceEqual(y.Arguments);
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)