diff --git a/src/EllieBot.Generators/Cloneable/CloneableGenerator.cs b/src/EllieBot.Generators/Cloneable/CloneableGenerator.cs index 6bd7da4..4b5f8cb 100644 --- a/src/EllieBot.Generators/Cloneable/CloneableGenerator.cs +++ b/src/EllieBot.Generators/Cloneable/CloneableGenerator.cs @@ -6,8 +6,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -using System.Collections.Generic; -using System.Linq; using System.Text; namespace Cloneable @@ -23,54 +21,60 @@ namespace Cloneable private const string CLONE_ATTRIBUTE_STRING = "CloneAttribute"; private const string IGNORE_CLONE_ATTRIBUTE_STRING = "IgnoreCloneAttribute"; - private const string CLONEABLE_ATTRIBUTE_TEXT = @"// -using System; + private const string CLONEABLE_ATTRIBUTE_TEXT = $$""" + // + using System; + + namespace {{CLONEABLE_NAMESPACE}} + { + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)] + internal sealed class {{CLONEABLE_ATTRIBUTE_STRING}} : Attribute + { + public {{CLONEABLE_ATTRIBUTE_STRING}}() + { + } + + public bool {{EXPLICIT_DECLARATION_KEY_STRING}} { get; set; } + } + } -namespace " + CLONEABLE_NAMESPACE + @" -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)] - public sealed class " + CLONEABLE_ATTRIBUTE_STRING + @" : Attribute - { - public " + CLONEABLE_ATTRIBUTE_STRING + @"() - { - } + """; - public bool " + EXPLICIT_DECLARATION_KEY_STRING + @" { get; set; } - } -} -"; + private const string CLONE_PROPERTY_ATTRIBUTE_TEXT = $$""" + // + using System; + + namespace {{CLONEABLE_NAMESPACE}} + { + [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] + internal sealed class {{CLONE_ATTRIBUTE_STRING}} : Attribute + { + public {{CLONE_ATTRIBUTE_STRING}}() + { + } + + public bool {{PREVENT_DEEP_COPY_KEY_STRING}} { get; set; } + } + } - private const string CLONE_PROPERTY_ATTRIBUTE_TEXT = @"// -using System; + """; -namespace " + CLONEABLE_NAMESPACE + @" -{ - [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] - public sealed class " + CLONE_ATTRIBUTE_STRING + @" : Attribute - { - public " + CLONE_ATTRIBUTE_STRING + @"() - { - } + private const string IGNORE_CLONE_PROPERTY_ATTRIBUTE_TEXT = $$""" + // + using System; + + namespace {{CLONEABLE_NAMESPACE}} + { + [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] + internal sealed class {{IGNORE_CLONE_ATTRIBUTE_STRING}} : Attribute + { + public {{IGNORE_CLONE_ATTRIBUTE_STRING}}() + { + } + } + } - public bool " + PREVENT_DEEP_COPY_KEY_STRING + @" { get; set; } - } -} -"; - - private const string IGNORE_CLONE_PROPERTY_ATTRIBUTE_TEXT = @"// -using System; - -namespace " + CLONEABLE_NAMESPACE + @" -{ - [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] - public sealed class " + IGNORE_CLONE_ATTRIBUTE_STRING + @" : Attribute - { - public " + IGNORE_CLONE_ATTRIBUTE_STRING + @"() - { - } - } -} -"; + """; private INamedTypeSymbol? _cloneableAttribute; private INamedTypeSymbol? _ignoreCloneAttribute; @@ -180,7 +184,7 @@ namespace {namespaceName} }}"; } - private IEnumerable<(string line, bool isCloneable)> GenerateFieldAssignmentsCode(INamedTypeSymbol classSymbol, bool isExplicit) + private IEnumerable<(string line, bool isCloneable)> GenerateFieldAssignmentsCode(INamedTypeSymbol classSymbol, bool isExplicit ) { var fieldNames = GetCloneableProperties(classSymbol, isExplicit); diff --git a/src/EllieBot.Generators/Cloneable/SymbolExtensions.cs b/src/EllieBot.Generators/Cloneable/SymbolExtensions.cs index 6c0c605..8d6de76 100644 --- a/src/EllieBot.Generators/Cloneable/SymbolExtensions.cs +++ b/src/EllieBot.Generators/Cloneable/SymbolExtensions.cs @@ -1,8 +1,7 @@ // Code temporarily yeeted from // https://github.com/mostmand/Cloneable/blob/master/Cloneable/CloneableGenerator.cs // because of NRT issue -using System.Collections.Generic; -using System.Linq; + using Microsoft.CodeAnalysis; namespace Cloneable diff --git a/src/EllieBot.Generators/Cloneable/SyntaxReceiver.cs b/src/EllieBot.Generators/Cloneable/SyntaxReceiver.cs index 962c395..ae0d029 100644 --- a/src/EllieBot.Generators/Cloneable/SyntaxReceiver.cs +++ b/src/EllieBot.Generators/Cloneable/SyntaxReceiver.cs @@ -1,7 +1,7 @@ // Code temporarily yeeted from // https://github.com/mostmand/Cloneable/blob/master/Cloneable/CloneableGenerator.cs // because of NRT issue -using System.Collections.Generic; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/EllieBot.Generators/Command/CommandAttributesGenerator.cs b/src/EllieBot.Generators/Command/CommandAttributesGenerator.cs deleted file mode 100644 index 81a758c..0000000 --- a/src/EllieBot.Generators/Command/CommandAttributesGenerator.cs +++ /dev/null @@ -1,336 +0,0 @@ -// #nullable enable -// using System; -// using System.CodeDom.Compiler; -// using System.Collections.Generic; -// using System.Collections.Immutable; -// using System.Collections.ObjectModel; -// using System.Diagnostics; -// using System.IO; -// using System.Linq; -// using System.Text; -// using System.Threading; -// using Microsoft.CodeAnalysis; -// using Microsoft.CodeAnalysis.CSharp; -// using Microsoft.CodeAnalysis.CSharp.Syntax; -// using Microsoft.CodeAnalysis.Text; -// -// namespace EllieBot.Generators.Command; -// -// [Generator] -// public class CommandAttributesGenerator : IIncrementalGenerator -// { -// public const string ATTRIBUTE = @"// -// -// namespace EllieBot.Common; -// -// [System.AttributeUsage(System.AttributeTargets.Method)] -// public class CmdAttribute : System.Attribute -// { -// -// }"; -// -// public class MethodModel -// { -// public string? Namespace { get; } -// public IReadOnlyCollection Classes { get; } -// public string ReturnType { get; } -// public string MethodName { get; } -// public IEnumerable Params { get; } -// -// public MethodModel(string? ns, IReadOnlyCollection classes, string returnType, string methodName, IEnumerable @params) -// { -// Namespace = ns; -// Classes = classes; -// ReturnType = returnType; -// MethodName = methodName; -// Params = @params; -// } -// } -// -// public class FileModel -// { -// public string? Namespace { get; } -// public IReadOnlyCollection ClassHierarchy { get; } -// public IReadOnlyCollection Methods { get; } -// -// public FileModel(string? ns, IReadOnlyCollection classHierarchy, IReadOnlyCollection methods) -// { -// Namespace = ns; -// ClassHierarchy = classHierarchy; -// Methods = methods; -// } -// } -// -// public void Initialize(IncrementalGeneratorInitializationContext context) -// { -// // #if DEBUG -// // if (!Debugger.IsAttached) -// // Debugger.Launch(); -// // // SpinWait.SpinUntil(() => Debugger.IsAttached); -// // #endif -// context.RegisterPostInitializationOutput(static ctx => ctx.AddSource( -// "CmdAttribute.g.cs", -// SourceText.From(ATTRIBUTE, Encoding.UTF8))); -// -// var methods = context.SyntaxProvider -// .CreateSyntaxProvider( -// static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 }, -// static (ctx, cancel) => Transform(ctx, cancel)) -// .Where(static m => m is not null) -// .Where(static m => m?.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)) ?? false); -// -// var compilationMethods = context.CompilationProvider.Combine(methods.Collect()); -// -// context.RegisterSourceOutput(compilationMethods, -// static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right)); -// } -// -// private static void RegisterAction(in SourceProductionContext ctx, -// Compilation comp, -// in ImmutableArray methods) -// { -// if (methods is { IsDefaultOrEmpty: true }) -// return; -// -// var models = GetModels(comp, methods, ctx.CancellationToken); -// -// foreach (var model in models) -// { -// var name = $"{model.Namespace}.{string.Join(".", model.ClassHierarchy)}.g.cs"; -// try -// { -// var source = GetSourceText(model); -// ctx.AddSource(name, SourceText.From(source, Encoding.UTF8)); -// } -// catch (Exception ex) -// { -// Console.WriteLine($"Error writing source file {name}\n" + ex); -// } -// } -// } -// -// private static string GetSourceText(FileModel model) -// { -// using var sw = new StringWriter(); -// using var tw = new IndentedTextWriter(sw); -// -// tw.WriteLine("// "); -// tw.WriteLine("#pragma warning disable CS1066"); -// -// if (model.Namespace is not null) -// { -// tw.WriteLine($"namespace {model.Namespace};"); -// tw.WriteLine(); -// } -// -// foreach (var className in model.ClassHierarchy) -// { -// tw.WriteLine($"public partial class {className}"); -// tw.WriteLine("{"); -// tw.Indent ++; -// } -// -// foreach (var method in model.Methods) -// { -// tw.WriteLine("[EllieCommand]"); -// tw.WriteLine("[EllieDescription]"); -// tw.WriteLine("[Aliases]"); -// tw.WriteLine($"public partial {method.ReturnType} {method.MethodName}({string.Join(", ", method.Params)});"); -// } -// -// foreach (var _ in model.ClassHierarchy) -// { -// tw.Indent --; -// tw.WriteLine("}"); -// } -// -// tw.Flush(); -// return sw.ToString(); -// } -// -// private static IReadOnlyCollection GetModels(Compilation compilation, -// in ImmutableArray inputMethods, -// CancellationToken cancel) -// { -// var models = new List(); -// -// var methods = inputMethods -// .Where(static x => x is not null) -// .Distinct(); -// -// var methodModels = methods -// .Select(x => MethodDeclarationToMethodModel(compilation, x!)) -// .Where(static x => x is not null) -// .Cast(); -// -// var groups = methodModels -// .GroupBy(static x => $"{x.Namespace}.{string.Join(".", x.Classes)}"); -// -// foreach (var group in groups) -// { -// if (cancel.IsCancellationRequested) -// return new Collection(); -// -// if (group is null) -// continue; -// -// var elems = group.ToList(); -// if (elems.Count is 0) -// continue; -// -// var model = new FileModel( -// methods: elems, -// ns: elems[0].Namespace, -// classHierarchy: elems![0].Classes -// ); -// -// models.Add(model); -// } -// -// -// return models; -// } -// -// private static MethodModel? MethodDeclarationToMethodModel(Compilation comp, MethodDeclarationSyntax decl) -// { -// // SpinWait.SpinUntil(static () => Debugger.IsAttached); -// -// SemanticModel semanticModel; -// try -// { -// semanticModel = comp.GetSemanticModel(decl.SyntaxTree); -// } -// catch -// { -// // for some reason this method can throw "Not part of this compilation" argument exception -// return null; -// } -// -// var methodModel = new MethodModel( -// @params: decl.ParameterList.Parameters -// .Where(p => p.Type is not null) -// .Select(p => -// { -// var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword)) -// ? "params " -// : string.Empty; -// -// var type = semanticModel -// .GetTypeInfo(p.Type!) -// .Type -// ?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); -// -// -// var name = p.Identifier.Text; -// -// var suffix = string.Empty; -// if (p.Default is not null) -// { -// if (p.Default.Value is LiteralExpressionSyntax) -// { -// suffix = " = " + p.Default.Value; -// } -// else if (p.Default.Value is MemberAccessExpressionSyntax maes) -// { -// var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree); -// var sym = maesSemModel.GetSymbolInfo(maes.Name); -// if (sym.Symbol is null) -// { -// suffix = " = " + p.Default.Value; -// } -// else -// { -// suffix = " = " + sym.Symbol.ToDisplayString(); -// } -// } -// } -// -// return $"{prefix}{type} {name}{suffix}"; -// }) -// .ToList(), -// methodName: decl.Identifier.Text, -// returnType: decl.ReturnType.ToString(), -// ns: GetNamespace(decl), -// classes: GetClasses(decl) -// ); -// -// return methodModel; -// } -// -// //https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs -// static string? GetNamespace(MethodDeclarationSyntax declarationSyntax) -// { -// // determine the namespace the class is declared in, if any -// string? nameSpace = null; -// var parentOfInterest = declarationSyntax.Parent; -// while (parentOfInterest is not null) -// { -// parentOfInterest = parentOfInterest.Parent; -// -// if (parentOfInterest is BaseNamespaceDeclarationSyntax ns) -// { -// nameSpace = ns.Name.ToString(); -// while (true) -// { -// if (ns.Parent is not NamespaceDeclarationSyntax parent) -// { -// break; -// } -// -// ns = parent; -// nameSpace = $"{ns.Name}.{nameSpace}"; -// } -// -// return nameSpace; -// } -// -// } -// -// return nameSpace; -// } -// -// static IReadOnlyCollection GetClasses(MethodDeclarationSyntax declarationSyntax) -// { -// // determine the namespace the class is declared in, if any -// var classes = new LinkedList(); -// var parentOfInterest = declarationSyntax.Parent; -// while (parentOfInterest is not null) -// { -// if (parentOfInterest is ClassDeclarationSyntax cds) -// { -// classes.AddFirst(cds.Identifier.ToString()); -// } -// -// parentOfInterest = parentOfInterest.Parent; -// } -// -// Debug.WriteLine($"Method {declarationSyntax.Identifier.Text} has {classes.Count} classes"); -// -// return classes; -// } -// -// private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel) -// { -// var methodDecl = ctx.Node as MethodDeclarationSyntax; -// if (methodDecl is null) -// return default; -// -// foreach (var attListSyntax in methodDecl.AttributeLists) -// { -// foreach (var attSyntax in attListSyntax.Attributes) -// { -// if (cancel.IsCancellationRequested) -// return default; -// -// var symbol = ctx.SemanticModel.GetSymbolInfo(attSyntax).Symbol; -// if (symbol is not IMethodSymbol attSymbol) -// continue; -// -// if (attSymbol.ContainingType.ToDisplayString() == "EllieBot.Common.CmdAttribute") -// return methodDecl; -// } -// } -// -// return default; -// } -// } \ No newline at end of file diff --git a/src/EllieBot.Generators/EllieBot.Generators.csproj b/src/EllieBot.Generators/EllieBot.Generators.csproj index 742b2ea..1dbbc1d 100644 --- a/src/EllieBot.Generators/EllieBot.Generators.csproj +++ b/src/EllieBot.Generators/EllieBot.Generators.csproj @@ -5,6 +5,7 @@ latest false true + true diff --git a/src/EllieBot.Generators/LocalizedStringsGenerator.cs b/src/EllieBot.Generators/LocalizedStringsGenerator.cs index 95abda9..72d5040 100644 --- a/src/EllieBot.Generators/LocalizedStringsGenerator.cs +++ b/src/EllieBot.Generators/LocalizedStringsGenerator.cs @@ -1,10 +1,6 @@ #nullable enable -using System; using System.CodeDom.Compiler; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; using Newtonsoft.Json; @@ -26,24 +22,23 @@ namespace EllieBot.Generators [Generator] public class LocalizedStringsGenerator : ISourceGenerator { - private const string LOC_STR_SOURCE = @"namespace EllieBot -{ - public readonly struct LocStr - { - public readonly string Key; - public readonly object[] Params; - - public LocStr(string key, params object[] data) - { - Key = key; - Params = data; - } - } -}"; + // private const string LOC_STR_SOURCE = @"namespace EllieBot + // { + // public readonly struct LocStr + // { + // public readonly string Key; + // public readonly object[] Params; + // + // public LocStr(string key, params object[] data) + // { + // Key = key; + // Params = data; + // } + // } + // }"; public void Initialize(GeneratorInitializationContext context) { - } public void Execute(GeneratorExecutionContext context) @@ -55,6 +50,7 @@ namespace EllieBot.Generators using (var stringWriter = new StringWriter()) using (var sw = new IndentedTextWriter(stringWriter)) { + sw.WriteLine("#pragma warning disable CS8981"); sw.WriteLine("namespace EllieBot;"); sw.WriteLine(); @@ -106,7 +102,7 @@ namespace EllieBot.Generators context.AddSource("strs.g.cs", stringWriter.ToString()); } - context.AddSource("LocStr.g.cs", LOC_STR_SOURCE); + // context.AddSource("LocStr.g.cs", LOC_STR_SOURCE); } private List GetFields(string? dataText)