mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-19 13:41:46 +08:00
806287d7e2
This both adds the new "// <auto-generated/>" header, as well as restores the non-file-scoped namespace declaration so that the code will compile on C# < 10 as well (which is explicitly supported by the MVVM Toolkit)
57 lines
2.2 KiB
C#
57 lines
2.2 KiB
C#
// 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.
|
|
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
|
|
namespace CommunityToolkit.Mvvm.SourceGenerators;
|
|
|
|
/// <summary>
|
|
/// A source generator for necessary nullability attributes.
|
|
/// </summary>
|
|
[Generator]
|
|
public sealed class NullabilityAttributesGenerator : ISourceGenerator
|
|
{
|
|
/// <inheritdoc/>
|
|
public void Initialize(GeneratorInitializationContext context)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public void Execute(GeneratorExecutionContext context)
|
|
{
|
|
AddSourceCodeIfTypeIsNotPresent(context, "System.Diagnostics.CodeAnalysis.NotNullAttribute");
|
|
AddSourceCodeIfTypeIsNotPresent(context, "System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds the source for a given attribute type if it's not present already in the compilation.
|
|
/// </summary>
|
|
private void AddSourceCodeIfTypeIsNotPresent(GeneratorExecutionContext context, string typeFullName)
|
|
{
|
|
// Check that the target attributes are not available in the consuming project. To ensure that
|
|
// this works fine both in .NET (Core) and .NET Standard implementations, we also need to check
|
|
// that the target types are declared as public (we assume that in this case those types are from the BCL).
|
|
// This avoids issues on .NET Standard with Roslyn also seeing internal types from referenced assemblies.
|
|
if (context.Compilation.GetTypeByMetadataName(typeFullName) is { DeclaredAccessibility: Accessibility.Public })
|
|
{
|
|
return;
|
|
}
|
|
|
|
string typeName = typeFullName.Split('.').Last();
|
|
string filename = $"CommunityToolkit.Mvvm.SourceGenerators.EmbeddedResources.{typeName}.cs";
|
|
|
|
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(filename);
|
|
StreamReader reader = new(stream);
|
|
|
|
string source = reader.ReadToEnd();
|
|
|
|
context.AddSource($"{typeFullName}.cs", SourceText.From(source, Encoding.UTF8));
|
|
}
|
|
}
|