File: GenerateGlobalUsings.cs
Web Access
Project: ..\..\..\src\Tasks\Microsoft.NET.Build.Tasks\Microsoft.NET.Build.Tasks.csproj (Microsoft.NET.Build.Tasks)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
#nullable disable
 
using Microsoft.Build.Framework;
 
namespace Microsoft.NET.Build.Tasks
{
    public sealed class GenerateGlobalUsings : TaskBase
    {
        [Required]
        public ITaskItem[] Usings { get; set; }
 
        [Output]
        public string[] Lines { get; set; }
 
        protected override void ExecuteCore()
        {
            if (Usings.Length == 0)
            {
                Lines = Array.Empty<string>();
                return;
            }
 
            var usings = Usings.Select(UsingInfo.Read)
                .OrderBy(static k => k, UsingInfoComparer.Instance)
                .Distinct(UsingInfoComparer.Instance);
 
            var lines = new string[Usings.Length + 1];
            lines[0] = "// <auto-generated/>";
 
            var index = 1;
            var lineBuilder = new StringBuilder();
            foreach (var @using in usings)
            {
                lineBuilder.Clear();
                lineBuilder.Append("global using ");
 
                if (@using.Static)
                {
                    lineBuilder.Append("static ");
                }
 
                if (!string.IsNullOrEmpty(@using.Alias))
                {
                    lineBuilder.Append(@using.Alias)
                        .Append(" = ");
                }
 
                lineBuilder.Append(@using.Namespace)
                    .Append(';');
 
                lines[index++] = lineBuilder.ToString();
            }
 
            Lines = lines;
        }
 
        private readonly struct UsingInfo
        {
            public static UsingInfo Read(ITaskItem taskItem)
            {
                return new UsingInfo(
                    taskItem.ItemSpec,
                    taskItem.GetBooleanMetadata("Static") == true,
                    taskItem.GetMetadata("Alias"));
            }
 
            private UsingInfo(string @namespace, bool @static, string alias)
            {
                Namespace = @namespace;
                Static = @static;
                Alias = alias;
            }
 
            public string Namespace { get; }
            public bool Static { get; }
            public string Alias { get; }
        }
 
        private sealed class UsingInfoComparer : IComparer<UsingInfo>, IEqualityComparer<UsingInfo>
        {
            public static readonly UsingInfoComparer Instance = new();
 
            public int Compare(UsingInfo x, UsingInfo y)
            {
                var @static = x.Static.CompareTo(y.Static);
                if (@static != 0)
                {
                    return @static;
                }
 
                var alias = x.Alias.CompareTo(y.Alias);
                if (alias != 0)
                {
                    return alias;
                }
 
                return StringComparer.Ordinal.Compare(x.Namespace, y.Namespace);
            }
 
            public bool Equals(UsingInfo x, UsingInfo y)
            {
                return Compare(x, y) == 0;
            }
 
            public int GetHashCode(UsingInfo obj)
            {
                return StringComparer.Ordinal.GetHashCode(obj.Namespace);
            }
        }
    }
}