-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix incremental source generator #22
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
b77a1b1
Fix incremental source generator
GerardSmit 895a0a0
Switch to CRLF line ending
virzak 21ab2c3
Use Microsoft.Bcl.HashCode package, which is nearly identical to Hash…
virzak 4107aa8
Remove EquatableEnum and cast to ushort
virzak ef5aa7a
Exclude EquatableArray from code coverage and add remarks
virzak 12f3e4b
Exclude EquatableArray extension method from code coverage
virzak 29bf724
Allow 85% code coverage
virzak 04a1353
Ensure Microsoft.Bcl.HashCode is available at generation time
virzak 310aed4
Implement xUnit suggestion
virzak de2c824
Move usings into csproj
virzak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
coverage: | ||
status: | ||
project: | ||
default: | ||
threshold: 10% | ||
patch: | ||
default: | ||
threshold: 10% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections; | ||
using System.Diagnostics.CodeAnalysis; | ||
|
||
namespace Zomp.SyncMethodGenerator.Helpers; | ||
|
||
/// <summary> | ||
/// An immutable, equatable array. This is equivalent to <see cref="ImmutableArray{T}"/> but with value equality support. | ||
/// </summary> | ||
/// <typeparam name="T">The type of values in the array.</typeparam> | ||
/// <remarks> | ||
/// Modified from: https://github.com/dotnet/runtime/issues/77183#issuecomment-1284577055. | ||
/// Remove this struct when the issue above is resolved. | ||
/// </remarks> | ||
[ExcludeFromCodeCoverage] | ||
internal readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T> | ||
where T : IEquatable<T> | ||
{ | ||
/// <summary> | ||
/// The underlying <typeparamref name="T"/> array. | ||
/// </summary> | ||
private readonly T[]? array; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="EquatableArray{T}"/> struct. | ||
/// </summary> | ||
/// <param name="array">The input <see cref="ImmutableArray{T}"/> to wrap.</param> | ||
public EquatableArray(ImmutableArray<T> array) | ||
{ | ||
this.array = Unsafe.As<ImmutableArray<T>, T[]?>(ref array); | ||
} | ||
|
||
/// <summary> | ||
/// Gets a value indicating whether the current array is empty. | ||
/// </summary> | ||
public bool IsEmpty | ||
{ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
get => AsImmutableArray().IsEmpty; | ||
} | ||
|
||
/// <summary> | ||
/// Gets a reference to an item at a specified position within the array. | ||
/// </summary> | ||
/// <param name="index">The index of the item to retrieve a reference to.</param> | ||
/// <returns>A reference to an item at a specified position within the array.</returns> | ||
public ref readonly T this[int index] | ||
{ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
get => ref AsImmutableArray().ItemRef(index); | ||
} | ||
|
||
/// <summary> | ||
/// Implicitly converts an <see cref="ImmutableArray{T}"/> to <see cref="EquatableArray{T}"/>. | ||
/// </summary> | ||
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns> | ||
public static implicit operator EquatableArray<T>(ImmutableArray<T> array) | ||
{ | ||
return FromImmutableArray(array); | ||
} | ||
|
||
/// <summary> | ||
/// Implicitly converts an <see cref="EquatableArray{T}"/> to <see cref="ImmutableArray{T}"/>. | ||
/// </summary> | ||
/// <returns>An <see cref="ImmutableArray{T}"/> instance from a given <see cref="EquatableArray{T}"/>.</returns> | ||
public static implicit operator ImmutableArray<T>(EquatableArray<T> array) | ||
{ | ||
return array.AsImmutableArray(); | ||
} | ||
|
||
/// <summary> | ||
/// Checks whether two <see cref="EquatableArray{T}"/> values are the same. | ||
/// </summary> | ||
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param> | ||
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param> | ||
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are equal.</returns> | ||
public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right) | ||
{ | ||
return left.Equals(right); | ||
} | ||
|
||
/// <summary> | ||
/// Checks whether two <see cref="EquatableArray{T}"/> values are not the same. | ||
/// </summary> | ||
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param> | ||
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param> | ||
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are not equal.</returns> | ||
public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right) | ||
{ | ||
return !left.Equals(right); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>. | ||
/// </summary> | ||
/// <param name="array">The input <see cref="ImmutableArray{T}"/> instance.</param> | ||
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns> | ||
public static EquatableArray<T> FromImmutableArray(ImmutableArray<T> array) | ||
{ | ||
return new(array); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public bool Equals(EquatableArray<T> array) | ||
{ | ||
return AsSpan().SequenceEqual(array.AsSpan()); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override bool Equals([NotNullWhen(true)] object? obj) | ||
{ | ||
return obj is EquatableArray<T> array && Equals(this, array); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override int GetHashCode() | ||
{ | ||
if (this.array is not T[] array) | ||
{ | ||
return 0; | ||
} | ||
|
||
HashCode hashCode = default; | ||
|
||
foreach (T item in array) | ||
{ | ||
hashCode.Add(item); | ||
} | ||
|
||
return hashCode.ToHashCode(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets an <see cref="ImmutableArray{T}"/> instance from the current <see cref="EquatableArray{T}"/>. | ||
/// </summary> | ||
/// <returns>The <see cref="ImmutableArray{T}"/> from the current <see cref="EquatableArray{T}"/>.</returns> | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public ImmutableArray<T> AsImmutableArray() | ||
{ | ||
return Unsafe.As<T[]?, ImmutableArray<T>>(ref Unsafe.AsRef(in array)); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a <see cref="ReadOnlySpan{T}"/> wrapping the current items. | ||
/// </summary> | ||
/// <returns>A <see cref="ReadOnlySpan{T}"/> wrapping the current items.</returns> | ||
public ReadOnlySpan<T> AsSpan() | ||
{ | ||
return AsImmutableArray().AsSpan(); | ||
} | ||
|
||
/// <summary> | ||
/// Copies the contents of this <see cref="EquatableArray{T}"/> instance to a mutable array. | ||
/// </summary> | ||
/// <returns>The newly instantiated array.</returns> | ||
public T[] ToArray() | ||
{ | ||
return AsImmutableArray().ToArray(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets an <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array. | ||
/// </summary> | ||
/// <returns>An <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array.</returns> | ||
public ImmutableArray<T>.Enumerator GetEnumerator() | ||
{ | ||
return AsImmutableArray().GetEnumerator(); | ||
} | ||
|
||
/// <inheritdoc/> | ||
IEnumerator<T> IEnumerable<T>.GetEnumerator() | ||
{ | ||
return ((IEnumerable<T>)AsImmutableArray()).GetEnumerator(); | ||
} | ||
|
||
/// <inheritdoc/> | ||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return ((IEnumerable)AsImmutableArray()).GetEnumerator(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Extensions for <see cref="EquatableArray{T}"/>. | ||
/// </summary> | ||
[ExcludeFromCodeCoverage] | ||
internal static class EquatableArray | ||
{ | ||
/// <summary> | ||
/// Creates an <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The type of items in the input array.</typeparam> | ||
/// <param name="array">The input <see cref="ImmutableArray{T}"/> instance.</param> | ||
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns> | ||
public static EquatableArray<T> AsEquatableArray<T>(this ImmutableArray<T> array) | ||
where T : IEquatable<T> | ||
{ | ||
return new(array); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
namespace Zomp.SyncMethodGenerator.Models; | ||
|
||
/// <summary> | ||
/// Basic diagnostic description for reporting diagnostic inside the incremental pipeline. | ||
/// </summary> | ||
/// <param name="Descriptor">Diagnostic descriptor.</param> | ||
/// <param name="FilePath">File path.</param> | ||
/// <param name="TextSpan">Text span.</param> | ||
/// <param name="LineSpan">Line span.</param> | ||
/// <param name="Trivia">Trivia.</param> | ||
/// <see href="https://github.com/dotnet/roslyn/issues/62269#issuecomment-1170760367" /> | ||
internal sealed record ReportedDiagnostic(DiagnosticDescriptor Descriptor, string FilePath, TextSpan TextSpan, LinePositionSpan LineSpan, string Trivia) | ||
{ | ||
/// <summary> | ||
/// Implicitly converts <see cref="ReportedDiagnostic"/> to <see cref="Diagnostic"/>. | ||
/// </summary> | ||
/// <param name="diagnostic">Diagnostic to convert.</param> | ||
public static implicit operator Diagnostic(ReportedDiagnostic diagnostic) | ||
{ | ||
return Diagnostic.Create( | ||
descriptor: diagnostic.Descriptor, | ||
location: Location.Create(diagnostic.FilePath, diagnostic.TextSpan, diagnostic.LineSpan), | ||
messageArgs: new object[] { diagnostic.Trivia }); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="ReportedDiagnostic"/> from <see cref="DiagnosticDescriptor"/> and <see cref="Location"/>. | ||
/// </summary> | ||
/// <param name="descriptor">Descriptor.</param> | ||
/// <param name="location">Location.</param> | ||
/// <param name="trivia">Trivia.</param> | ||
/// <returns>A new <see cref="ReportedDiagnostic"/>.</returns> | ||
public static ReportedDiagnostic Create(DiagnosticDescriptor descriptor, Location location, string trivia) | ||
{ | ||
return new(descriptor, location.SourceTree?.FilePath ?? string.Empty, location.SourceSpan, location.GetLineSpan().Span, trivia); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work without including the dependency in the NuGet package?
Aka https://github.com/dotnet/roslyn/blob/main/docs/features/source-generators.cookbook.md#use-functionality-from-nuget-packages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsoft, soon. Most likely this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GerardSmit, thanks for pointing that out. Will ensure it gets included. BTW, if any of the commits I made after your original PR don't make sense, let me know. We should have this merged soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything else look OK to me; using a ushort instead of a hacky wrapper struct is probably better. 😉