//using Microsoft.CodeAnalysis; //using Microsoft.CodeAnalysis.CSharp.Syntax; //using Microsoft.CodeAnalysis.Text; //using System.Collections.Generic; //using System.Collections.Immutable; //using System.Linq; //using System.Text; //namespace QWERTYkez.Mensura.Generator; //[Generator(LanguageNames.CSharp)] //internal class CollectionsOperatorsGenerator : IIncrementalGenerator //{ // private const string AttributeShortName = "CollectionsOperatorsGenerator"; // private const string AttributeFullName = AttributeShortName + "Attribute"; // private const string AttributeSource = @"namespace QWERTYkez.Mensura; //[System.AttributeUsage(System.AttributeTargets.Struct | System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)] //internal sealed class CollectionsOperatorsGeneratorAttribute : System.Attribute { }"; // public void Initialize(IncrementalGeneratorInitializationContext context) // { // context.RegisterPostInitializationOutput(context => // context.AddSource( // $"{AttributeFullName}.g", // SourceText.From(AttributeSource, Encoding.UTF8))); // var operatorsPipeline = // context.SyntaxProvider.CreateSyntaxProvider>>( // (node, _) => // { // if (node is ClassDeclarationSyntax cds) // { // SyntaxNode sn = cds; // while (sn.Parent is not null && // sn.Parent is not FileScopedNamespaceDeclarationSyntax) // { // sn = sn.Parent; // } // if (sn.Parent is FileScopedNamespaceDeclarationSyntax // && cds.TypeParameterList is null // && // ((cds.Members.OfType() // .Where(m => m.AttributeLists.SelectMany(al => al.Attributes) // .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName))) // .Any()) // || // (cds.Modifiers.Any(m => m.Text == "partial") // && cds.AttributeLists // .SelectMany(al => al.Attributes) // .Any(a => a.Name // .GetText() // .ToString() // .Contains(AttributeShortName))))) // { // return true; // } // } // return false; // }, // (syntax, _) => // { // string nameSpace; // var cds = (ClassDeclarationSyntax)syntax.Node; // { // SyntaxNode sn = cds; // while (sn.Parent is not FileScopedNamespaceDeclarationSyntax) // { // sn = sn.Parent!; // } // var nds = (FileScopedNamespaceDeclarationSyntax)sn.Parent; // nameSpace = nds.Name.ToString(); // } // var Res = new StringBuilder(); // { // Res.Append(cds.Modifiers); // Res.Append(" class "); // Res.Append(cds.Identifier.Text); // Res.Append(" "); // Res.Append(cds.BaseList); // Res.Append(" "); // Res.Append(cds.ConstraintClauses); // } // var operators = cds.Members.OfType() // .Where(m => m.AttributeLists // .SelectMany(al => al.Attributes) // .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName))) // .Where(mb => mb.ParameterList.Parameters.Count == 2) // .Select(mb => new Operation() // { // ReturnType = mb.ReturnType.ToString(), // OperatorToken = mb.OperatorToken.Text, // TypeA = mb.ParameterList.Parameters[0].Type!.ToString(), // TypeB = mb.ParameterList.Parameters[1].Type!.ToString(), // }); // return new(new(nameSpace, cds.Identifier.Text, Res.ToString()), [.. operators]); // }) // .Collect(); // context.RegisterSourceOutput(operatorsPipeline, GenerateOperators); // } // readonly static string[] CollectionTypes = ["MetricArray", "MetricList", "MetricObservableCollection"]; // static void GenerateOperators(SourceProductionContext context, ImmutableArray>> pairs) // { // foreach (var ng in pairs.GroupBy(c => c.Key.NameSpace)) // { // StringBuilder document = new("namespace "); // document.Append(ng.Key); // document.Append(";"); // var classes = ng.ToList().Select(c => (ClassData?)c.Key).ToList(); // var operations = ng.ToList().SelectMany(c => c.Value).ToList(); // var multiplications = operations.Where(op => op.OperatorToken == "*").ToList(); // var divisions = operations.Where(op => op.OperatorToken == "/").ToList(); // foreach (var ops in multiplications.GroupBy(op => op.TypeA)) // { // var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); // if (Class is not null) // { // document.AppendLine(); // document.AppendLine(); // document.AppendLine(Class.Value.ClassHeader); // document.AppendLine("{"); // foreach (var op in ops) // foreach (var ct in CollectionTypes) // { // document.AppendLine(@$" // public static {ct}<{op.ReturnType}> operator *({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left * UU); // public static {ct}<{op.ReturnType}> operator *({ct}<{op.TypeB}> left, {op.TypeA} right) => left.MetricSelect(UU => UU * right); //"); // } // document.Append("}"); // } // else // { // context.ReportDiagnostic(Diagnostic.Create(new( // "MSG0001", // "Need a class with an attribute", // $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", // "category", // DiagnosticSeverity.Error, // true), null, ops.Key)); // } // } // foreach (var ops in divisions.GroupBy(op => op.TypeA)) // { // var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); // if (Class is not null) // { // document.AppendLine(); // document.AppendLine(); // document.AppendLine(Class.Value.ClassHeader); // document.AppendLine("{"); // foreach (var op in ops) // foreach (var ct in CollectionTypes) // { // document.AppendLine(@$" // public static {ct}<{op.ReturnType}> operator /({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left / UU); //"); // } // document.Append("}"); // } // else // { // context.ReportDiagnostic(Diagnostic.Create(new( // "MSG0001", // "Need a class with an attribute", // $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", // "category", // DiagnosticSeverity.Error, // true), null, ops.Key)); // } // } // foreach (var ops in divisions.GroupBy(op => op.TypeB)) // { // var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); // if (Class is not null) // { // document.AppendLine(); // document.AppendLine(); // document.AppendLine(Class.Value.ClassHeader); // document.AppendLine("{"); // foreach (var op in ops) // foreach (var ct in CollectionTypes) // { // document.AppendLine(@$" // public static {ct}<{op.ReturnType}> operator /({ct}<{op.TypeA}> left, {op.TypeB} right) => left.MetricSelect(UU => UU / right); //"); // } // document.Append("}"); // } // else // { // context.ReportDiagnostic(Diagnostic.Create(new( // "MSG0001", // "Need a class with an attribute", // $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", // "category", // DiagnosticSeverity.Error, // true), null, ops.Key)); // } // } // context.AddSource($"operations.{ng.Key}.g", document.ToString()); // } // } //} //public struct ClassData(string nameSpace, string className, string classHeader) //{ // public string NameSpace = nameSpace; // public string ClassName = className; // public string ClassHeader = classHeader; //} //public struct Operation(string operatorToken, string typeA, string typeB, string returnType) //{ // public string ReturnType = returnType; // public string OperatorToken = operatorToken; // public string TypeA = typeA; // public string TypeB = typeB; //}