Port incremental helpers from ComputeSharp

Also added attribution in ThirdPartyNotices.txt
This commit is contained in:
Sergio Pedri 2021-12-13 18:06:07 +01:00
Родитель 85d2c0f166
Коммит 84c3e291ba
7 изменённых файлов: 320 добавлений и 3 удалений

Просмотреть файл

@ -2,6 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
@ -15,7 +19,7 @@ internal static class DiagnosticExtensions
/// <summary>
/// Adds a new diagnostics to the current compilation.
/// </summary>
/// <param name="context">The <see cref="GeneratorEditContext"/> instance currently in use.</param>
/// <param name="context">The <see cref="GeneratorExecutionContext"/> instance currently in use.</param>
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
/// <param name="symbol">The source <see cref="ISymbol"/> to attach the diagnostics to.</param>
/// <param name="args">The optional arguments for the formatted message to include.</param>
@ -31,7 +35,7 @@ internal static class DiagnosticExtensions
/// <summary>
/// Adds a new diagnostics to the current compilation.
/// </summary>
/// <param name="context">The <see cref="GeneratorEditContext"/> instance currently in use.</param>
/// <param name="context">The <see cref="GeneratorExecutionContext"/> instance currently in use.</param>
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
/// <param name="node">The source <see cref="SyntaxNode"/> to attach the diagnostics to.</param>
/// <param name="args">The optional arguments for the formatted message to include.</param>
@ -43,4 +47,52 @@ internal static class DiagnosticExtensions
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, node.GetLocation(), args));
}
/// <summary>
/// Adds a new diagnostics to the target builder.
/// </summary>
/// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param>
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
/// <param name="symbol">The source <see cref="ISymbol"/> to attach the diagnostics to.</param>
/// <param name="args">The optional arguments for the formatted message to include.</param>
public static void Add(
this ImmutableArray<Diagnostic>.Builder diagnostics,
DiagnosticDescriptor descriptor,
ISymbol symbol,
params object[] args)
{
diagnostics.Add(Diagnostic.Create(descriptor, symbol.Locations.FirstOrDefault(), args));
}
/// <summary>
/// Adds a new diagnostics to the target builder.
/// </summary>
/// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param>
/// <param name="descriptor">The input <see cref="DiagnosticDescriptor"/> for the diagnostics to create.</param>
/// <param name="node">The source <see cref="SyntaxNode"/> to attach the diagnostics to.</param>
/// <param name="args">The optional arguments for the formatted message to include.</param>
public static void Add(
this ImmutableArray<Diagnostic>.Builder diagnostics,
DiagnosticDescriptor descriptor,
SyntaxNode node,
params object[] args)
{
diagnostics.Add(Diagnostic.Create(descriptor, node.GetLocation(), args));
}
/// <summary>
/// Registers an output node into an <see cref="IncrementalGeneratorInitializationContext"/> to output diagnostics.
/// </summary>
/// <param name="context">The input <see cref="IncrementalGeneratorInitializationContext"/> instance.</param>
/// <param name="diagnostics">The input <see cref="IncrementalValuesProvider{TValues}"/> sequence of diagnostics.</param>
public static void ReportDiagnostics(this IncrementalGeneratorInitializationContext context, IncrementalValuesProvider<ImmutableArray<Diagnostic>> diagnostics)
{
context.RegisterSourceOutput(diagnostics, static (context, diagnostics) =>
{
foreach (Diagnostic diagnostic in diagnostics)
{
context.ReportDiagnostic(diagnostic);
}
});
}
}

Просмотреть файл

@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System;
using System.Collections.Generic;
using System.Linq;

Просмотреть файл

@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
/// <summary>
/// Extension methods for <see cref="HashCode"/>.
/// </summary>
internal static class HashCodeExtensions
{
/// <summary>
/// Adds all items from a given <see cref="ImmutableArray{T}"/> instance to an hashcode.
/// </summary>
/// <typeparam name="T">The type of items to hash.</typeparam>
/// <param name="hashCode">The target <see cref="HashCode"/> instance.</param>
/// <param name="items">The input items to hash.</param>
public static void AddRange<T>(this ref HashCode hashCode, ImmutableArray<T> items)
{
foreach (T item in items)
{
hashCode.Add(item);
}
}
/// <summary>
/// Adds all items from a given <see cref="ImmutableArray{T}"/> instance to an hashcode.
/// </summary>
/// <typeparam name="T">The type of items to hash.</typeparam>
/// <param name="hashCode">The target <see cref="HashCode"/> instance.</param>
/// <param name="comparer">A comparer to get hashcodes for <typeparamref name="T"/> items.</param>
/// <param name="items">The input items to hash.</param>
public static void AddRange<T>(this ref HashCode hashCode, ImmutableArray<T> items, IEqualityComparer<T> comparer)
{
foreach (T item in items)
{
hashCode.Add(item, comparer);
}
}
}

Просмотреть файл

@ -0,0 +1,78 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
/// <summary>
/// Extension methods for <see cref="IncrementalValuesProvider{TValues}"/>.
/// </summary>
internal static class IncrementalValuesProviderExtensions
{
/// <summary>
/// Creates a new <see cref="IncrementalValuesProvider{TValues}"/> instance with a gven pair of comparers.
/// </summary>
/// <typeparam name="TLeft">The type of left items in each tuple.</typeparam>
/// <typeparam name="TRight">The type of right items in each tuple.</typeparam>
/// <param name="source">The input <see cref="IncrementalValuesProvider{TValues}"/> instance.</param>
/// <param name="comparerLeft">An <see cref="IEqualityComparer{T}"/> instance for <typeparamref name="TLeft"/> items.</param>
/// <param name="comparerRight">An <see cref="IEqualityComparer{T}"/> instance for <typeparamref name="TRight"/> items.</param>
/// <returns>An <see cref="IncrementalValuesProvider{TValues}"/> with the specified comparers applied to each item.</returns>
public static IncrementalValuesProvider<(TLeft Left, TRight Right)> WithComparers<TLeft, TRight>(
this IncrementalValuesProvider<(TLeft Left, TRight Right)> source,
IEqualityComparer<TLeft> comparerLeft,
IEqualityComparer<TRight> comparerRight)
{
return source.WithComparer(new Comparer<TLeft, TRight>(comparerLeft, comparerRight));
}
/// <summary>
/// An <see cref="IEqualityComparer{T}"/> implementation for a value tuple.
/// </summary>
public sealed class Comparer<TLeft, TRight> : IEqualityComparer<(TLeft Left, TRight Right)>
{
/// <summary>
/// The <typeparamref name="TLeft"/> comparer.
/// </summary>
private readonly IEqualityComparer<TLeft> comparerLeft;
/// <summary>
/// The <typeparamref name="TRight"/> comparer.
/// </summary>
private readonly IEqualityComparer<TRight> comparerRight;
/// <summary>
/// Creates a new <see cref="Comparer{TLeft, TRight}"/> instance with the specified parameters.
/// </summary>
/// <param name="comparerLeft">The <typeparamref name="TLeft"/> comparer.</param>
/// <param name="comparerRight">The <typeparamref name="TRight"/> comparer.</param>
public Comparer(IEqualityComparer<TLeft> comparerLeft, IEqualityComparer<TRight> comparerRight)
{
this.comparerLeft = comparerLeft;
this.comparerRight = comparerRight;
}
/// <inheritdoc/>
public bool Equals((TLeft Left, TRight Right) x, (TLeft Left, TRight Right) y)
{
return
this.comparerLeft.Equals(x.Left, y.Left) &&
this.comparerRight.Equals(x.Right, y.Right);
}
/// <inheritdoc/>
public int GetHashCode((TLeft Left, TRight Right) obj)
{
return HashCode.Combine(
this.comparerLeft.GetHashCode(obj.Left),
this.comparerRight.GetHashCode(obj.Right));
}
}
}

Просмотреть файл

@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
using Microsoft.CodeAnalysis;
using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle;
namespace CommunityToolkit.Mvvm.SourceGenerators.Models;
/// <summary>
/// A model describing the hierarchy info for a specific type.
/// </summary>
/// <param name="FilenameHint">The filename hint for the current type.</param>
/// <param name="MetadataName">The metadata name for the current type.</param>
/// <param name="Namespace">Gets the namespace for the current type.</param>
/// <param name="Names">Gets the sequence of type definitions containing the current type.</param>
internal sealed record HierarchyInfo(string FilenameHint, string MetadataName, string Namespace, ImmutableArray<string> Names)
{
/// <summary>
/// Creates a new <see cref="HierarchyInfo"/> instance from a given <see cref="INamedTypeSymbol"/>.
/// </summary>
/// <param name="typeSymbol">The input <see cref="INamedTypeSymbol"/> instance to gather info for.</param>
/// <returns>A <see cref="HierarchyInfo"/> instance describing <paramref name="typeSymbol"/>.</returns>
public static HierarchyInfo From(INamedTypeSymbol typeSymbol)
{
ImmutableArray<string>.Builder names = ImmutableArray.CreateBuilder<string>();
for (INamedTypeSymbol? parent = typeSymbol;
parent is not null;
parent = parent.ContainingType)
{
names.Add(parent.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
}
return new(
typeSymbol.GetFullMetadataNameForFileName(),
typeSymbol.MetadataName,
typeSymbol.ContainingNamespace.ToDisplayString(new(typeQualificationStyle: NameAndContainingTypesAndNamespaces)),
names.ToImmutable());
}
/// <summary>
/// An <see cref="IEqualityComparer{T}"/> implementation for <see cref="HierarchyInfo"/>.
/// </summary>
public sealed class Comparer : IEqualityComparer<HierarchyInfo>
{
/// <summary>
/// The singleton <see cref="Comparer"/> instance.
/// </summary>
public static Comparer Default { get; } = new();
/// <inheritdoc/>
public bool Equals(HierarchyInfo? x, HierarchyInfo? y)
{
if (x is null && y is null)
{
return true;
}
if (x is null || y is null)
{
return false;
}
if (ReferenceEquals(x, y))
{
return true;
}
return
x.FilenameHint == y.FilenameHint &&
x.MetadataName == y.MetadataName &&
x.Namespace == y.Namespace &&
x.Names.SequenceEqual(y.Names);
}
/// <inheritdoc/>
public int GetHashCode(HierarchyInfo obj)
{
return HashCode.Combine(obj.Namespace, obj.MetadataName, obj.Names, obj.Names[0]);
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
namespace CommunityToolkit.Mvvm.SourceGenerators.Models;
/// <summary>
/// A model representing a value and an associated set of diagnostic errors.
/// </summary>
/// <typeparam name="TValue">The type of the wrapped value.</typeparam>
/// <param name="Value">The wrapped value for the current result.</param>
/// <param name="Errors">The associated diagnostic errors, if any.</param>
internal sealed record Result<TValue>(TValue Value, ImmutableArray<Diagnostic> Errors);

Просмотреть файл

@ -11,6 +11,7 @@ This project incorporates components from the projects listed below. The origina
4. PrivateObject/PrivateType (https://github.com/microsoft/testfx/tree/664ac7c2ac9dbfbee9d2a0ef560cfd72449dfe34/src/TestFramework/Extension.Desktop), included in UnitTests.
5. QuinnDamerell/UniversalMarkdown (https://github.com/QuinnDamerell/UniversalMarkdown) contributed by Quinn Damerell and Paul Bartrum for the MarkdownTextBlock control, relicensed to this .NET Foundation project under the MIT license upon contribution in https://github.com/CommunityToolkit/WindowsCommunityToolkit/pull/772.
6. qmatteoq/DesktopBridgeHelpers commit e278153 (https://github.com/qmatteoq/DesktopBridgeHelpers), contributed by Matteo Pagani to identify if running with identity in DesktopNotificationManagerCompat.cs and DesktopBridgeHelpers.cs, relicensed to this .NET Foundation project under the MIT license upon contribution in https://github.com/CommunityToolkit/WindowsCommunityToolkit/pull/3457.
7. Sergio0694/ComputeSharp (https://github.com/Sergio0694/ComputeSharp), contributed by Sergio Pedri to reuse some helpers to support incremental generators in the MVVM Toolkit.
%% PedroLamas/DeferredEvents NOTICES AND INFORMATION BEGIN HERE
=========================================
@ -113,4 +114,30 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=========================================
END OF PrivateOject/PrivateType NOTICES AND INFORMATION
END OF PrivateOject/PrivateType NOTICES AND INFORMATION
%% Sergio0694/ComputeSharp NOTICES AND INFORMATION BEGIN HERE
=========================================
MIT License
Copyright (c) 2021 Sergio Pedri
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=========================================
END OF Sergio0694/ComputeSharp NOTICES AND INFORMATION