private static void ReportGeneratorDiagnostics(GeneratorExecutionContext context, SourceTextGenerator generator) => generator.Diagnostics.ToList().ForEach(diagnostic => context.ReportDiagnostic(diagnostic));
public void Execute(GeneratorExecutionContext context) { var fields = GetAircraftFields(context).ToList(); var builder = new StringBuilder(); builder.Append(@" using System; using Microsoft.Extensions.Logging; using Microsoft.FlightSimulator.SimConnect; namespace FlightRecorder.Client.SimConnectMSFS { public partial class Connector {"); builder.Append(@" private void RegisterAircraftPositionDefinition() { RegisterDataDefinition<AircraftPositionStruct>(DEFINITIONS.AircraftPosition"); foreach ((_, _, var variable, var unit, var type, _, _) in fields) { builder.Append($@", (""{variable}"", ""{unit}"", (SIMCONNECT_DATATYPE){type})"); } builder.Append(@" ); } "); builder.Append(@" private void RegisterAircraftPositionSetDefinition() { RegisterDataDefinition<AircraftPositionSetStruct>(DEFINITIONS.AircraftPositionSet"); foreach ((_, _, var variable, var unit, var type, var setType, _) in fields) { if (setType == null || setType == SetTypeDefault) { builder.Append($@", (""{variable}"", ""{unit}"", (SIMCONNECT_DATATYPE){type})"); } } builder.Append(@" ); } "); builder.Append(@" private void RegisterEvents() {"); var eventId = InitialEventID; foreach ((_, _, var variable, var unit, var type, var setType, var setBy) in fields) { if (setType == SetTypeEvent) { // TODO: warning if setBy is empty builder.Append($@" logger.LogDebug(""Register event {{eventName}} to ID {{eventID}}"", ""{setBy}"", {eventId}); simconnect.MapClientEventToSimEvent((EVENTS){eventId}, ""{setBy}"");"); eventId++; } } builder.Append(@" } "); builder.Append(@" public void TriggerEvents(AircraftPositionStruct current, AircraftPositionStruct expected) {"); eventId = InitialEventID; foreach ((_, var name, var variable, var unit, var type, var setType, var setBy) in fields) { if (setType == SetTypeEvent) { // TODO: warning if setBy is empty builder.Append($@" if (current.{name} != expected.{name}) {{ logger.LogDebug(""Trigger event {{eventName}}"", ""{setBy}""); simconnect.TransmitClientEvent(SimConnect.SIMCONNECT_OBJECT_ID_USER, (EVENTS){eventId}, 0, GROUPS.GENERIC, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); }} "); eventId++; } } builder.Append(@" } "); builder.Append(@" } }"); context.AddSource("ConnectorGenerator", SourceText.From(builder.ToString(), Encoding.UTF8)); }
// ReSharper disable once InconsistentNaming public static string[] GetMSBuildItems(this GeneratorExecutionContext context, string name) => context .AdditionalFiles .Where(f =>
private static void ReportProgress(GeneratorExecutionContext context, int count) => context.ReportDiagnostic( Diagnostic.Create(new DiagnosticDescriptor("GENS01", "System Generator", $"Extended {count} systems", "Generator", DiagnosticSeverity.Warning, true), null));
private string GenerateBody(GeneratorExecutionContext context, TypeDeclarationSyntax tds, bool snakeCase, List <string> externalInheritances, string ns) { var body = new List <string>(); var members = context.ParseMembers(tds, false, externalInheritances, out bool isPositionalRecord); if (!context.CancellationToken.IsCancellationRequested) { var arrayPropertyType = typeof(ArrayPropertyAttribute); foreach (var member in members) { var(symbol, typeSymbol, nullable) = member; // Object field name var fieldName = symbol.Name; // Data field name var dataFieldName = snakeCase ? fieldName.ToSnakeCase() : fieldName; // Field type name var typeName = typeSymbol.GetTypeName(nullable, ns); // ArrayProperty attribute data var arrayData = symbol.GetAttributeData(arrayPropertyType.FullName); // Value part string valuePart; if (typeSymbol.IsSimpleType()) { valuePart = $@"dic.GetExact<{typeName}>(""{dataFieldName}"")"; if (typeSymbol.Name == "String" && !nullable) { valuePart += "!"; } } else if (typeSymbol.TypeKind == TypeKind.Enum) { // Enum item type var enumSymbol = (INamedTypeSymbol)typeSymbol; var enumType = enumSymbol.EnumUnderlyingType?.Name ?? "Byte"; valuePart = $@"({typeName})dic.GetExact<{enumType}>(""{dataFieldName}"")"; } else if (typeSymbol.TypeKind == TypeKind.Array) { // Array type var arraySymbol = (IArrayTypeSymbol)typeSymbol; var itemTypeSymbol = arraySymbol.ElementType; if (!itemTypeSymbol.IsSimpleType()) { continue; } // Splitter var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ','); var arrayType = itemTypeSymbol.Name; if (arrayType.Equals("String")) { valuePart = $@"StringUtils.AsEnumerable(dic.GetExact<string?>(""{dataFieldName}""), '{splitter}').ToArray()"; } else { valuePart = $@"StringUtils.AsEnumerable<{arrayType}>(dic.GetExact<string?>(""{dataFieldName}""), '{splitter}').ToArray()"; } } else if (typeSymbol.IsList()) { // Item type var listSymbol = (INamedTypeSymbol)typeSymbol; var itemTypeSymbol = listSymbol.TypeArguments[0]; if (!itemTypeSymbol.IsSimpleType()) { continue; } // Splitter var splitter = Extensions.CharToString(arrayData?.GetValue <char?>("Splitter") ?? ','); var listType = itemTypeSymbol.Name; if (listType.Equals("String")) { valuePart = $@"StringUtils.AsEnumerable(dic.GetExact<string?>(""{dataFieldName}""), '{splitter}').ToList()"; } else { valuePart = $@"StringUtils.AsEnumerable<{listType}>(dic.GetExact<string?>(""{dataFieldName}""), '{splitter}').ToList()"; } } else { continue; } if (isPositionalRecord) { body.Add($@"{fieldName}: {valuePart}"); } else { body.Add($@"{fieldName} = {valuePart}"); } } } // Limitation: When inheritanted, please keep the same style // Define constructor for Positional Record if (isPositionalRecord) { return("(" + string.Join(",\n", body) + ")"); } return("{\n" + string.Join(",\n", body) + "\n}"); }
public void Execute(GeneratorExecutionContext context) { var syntaxXml = context.AdditionalFiles.SingleOrDefault(a => Path.GetFileName(a.Path) == "Syntax.xml"); if (syntaxXml == null) { context.ReportDiagnostic(Diagnostic.Create(s_MissingSyntaxXml, location: null)); return; } var syntaxXmlText = syntaxXml.GetText(); if (syntaxXmlText == null) { context.ReportDiagnostic(Diagnostic.Create(s_UnableToReadSyntaxXml, location: null)); return; } Tree tree; var reader = XmlReader.Create(new SourceTextReader(syntaxXmlText), new XmlReaderSettings { DtdProcessing = DtdProcessing.Prohibit }); try { var serializer = new XmlSerializer(typeof(Tree)); tree = (Tree)serializer.Deserialize(reader); } catch (InvalidOperationException ex) when(ex.InnerException is XmlException) { var xmlException = (XmlException)ex.InnerException; var line = syntaxXmlText.Lines[xmlException.LineNumber - 1]; // LineNumber is one-based. int offset = xmlException.LinePosition - 1; // LinePosition is one-based var position = line.Start + offset; var span = new TextSpan(position, 0); var lineSpan = syntaxXmlText.Lines.GetLinePositionSpan(span); context.ReportDiagnostic( Diagnostic.Create( s_SyntaxXmlError, location: Location.Create(syntaxXml.Path, span, lineSpan), xmlException.Message)); return; } TreeFlattening.FlattenChildren(tree); AddResult(writer => SourceWriter.WriteMain(writer, tree, context.CancellationToken), "Syntax.xml.Main.Generated.cs"); AddResult(writer => SourceWriter.WriteInternal(writer, tree, context.CancellationToken), "Syntax.xml.Internal.Generated.cs"); AddResult(writer => SourceWriter.WriteSyntax(writer, tree, context.CancellationToken), "Syntax.xml.Syntax.Generated.cs"); void AddResult(Action <TextWriter> writeFunction, string hintName) { // Write out the contents to a StringBuilder to avoid creating a single large string // in memory var stringBuilder = new StringBuilder(); using (var textWriter = new StringWriter(stringBuilder)) { writeFunction(textWriter); } // And create a SourceText from the StringBuilder, once again avoiding allocating a single massive string context.AddSource(hintName, SourceText.From(new StringBuilderReader(stringBuilder), stringBuilder.Length, encoding: Encoding.UTF8)); } }
public InpcClassGenerator CreateGenerator(ClassToImplement target, GeneratorExecutionContext context) =>
public TypeDeclarationContext(GeneratorExecutionContext ctx, TypeDeclarationSyntax syntax) { Syntax = syntax; SemanticModel = ctx.Compilation.GetSemanticModel(syntax.SyntaxTree); }
public void Execute(GeneratorExecutionContext context) { InjectCloneableAttributes(context); GenerateCloneMethods(context); }
public void Execute(GeneratorExecutionContext context) { Tracker = (AttributeTracker)context.SyntaxReceiver; Members = Tracker.GetMembers(context.Compilation); }
private static void InjectCloneableAttributes(GeneratorExecutionContext context) { context.AddSource(CloneableAttributeString, SourceText.From(cloneableAttributeText, Encoding.UTF8)); context.AddSource(CloneAttributeString, SourceText.From(clonePropertyAttributeText, Encoding.UTF8)); context.AddSource(IgnoreCloneAttributeString, SourceText.From(ignoreClonePropertyAttributeText, Encoding.UTF8)); }
public void Execute(GeneratorExecutionContext context) => throw new NotImplementedException();
public GeneratorContext(GeneratorExecutionContext generatorExecutionContext) { _syntaxCollector = (SyntaxCollector)generatorExecutionContext.SyntaxReceiver !; _compilationAnalysisContext = null; _generatorExecutionContext = generatorExecutionContext; }
private IReadOnlyList <string> GetGraphQLConfigFiles( GeneratorExecutionContext context) => context.AdditionalFiles .Select(t => t.Path) .Where(t => IOPath.GetFileName(t).EqualsOrdinal(".graphqlrc.json")) .ToList();
public void Execute(GeneratorExecutionContext context) { string ns = context.Compilation.AssemblyName ?? context.Compilation.ToString(); string className = $"PropertySync"; string fullName = $"{ns}.{className}"; Class stubClass = new Class(className).SetStatic(true) .SetNamespace(ns) .WithAccessibility(Accessibility.Internal) .WithMethod(SyncMethod.Stub()) .WithMethod(SyncMethodAll.Stub()) .WithMethod(SyncToDictMethod.Stub()) .WithMethod(SyncFromDictMethod.Stub()); Compilation compilation = GetStubCompilation(context, stubClass); INamedTypeSymbol?stubClassType = compilation.GetTypeByMetadataName(fullName); IEnumerable <(ITypeSymbol, ITypeSymbol)> calls = GetStubCalls(compilation, stubClassType); Class generatedClass = new Class(className).SetStatic(true) .SetNamespace(ns) .WithAccessibility(Accessibility.Internal); var generatedToTypes = new HashSet <ITypeSymbol>(SymbolEqualityComparer.Default); var generatedFromTypes = new HashSet <ITypeSymbol>(SymbolEqualityComparer.Default); var generatedSyncSrcTypes = new HashSet <ITypeSymbol>(SymbolEqualityComparer.Default); var generatedSyncTargetTypes = new HashSet <ITypeSymbol>(SymbolEqualityComparer.Default); if (calls.Any()) { foreach ((ITypeSymbol t1, ITypeSymbol t2) in calls) { if (t1 is null || t2 is null) { continue; } if (t1.ToString() == CommonTypes.StringDict) { if (generatedFromTypes.Contains(t2)) { continue; } generatedClass = generatedClass.WithMethod(new SyncFromDictMethod(t2).Build()); generatedFromTypes.Add(t2); } else if (t2.ToString() == CommonTypes.StringDict) { if (generatedToTypes.Contains(t1)) { continue; } generatedClass = generatedClass.WithMethod(new SyncToDictMethod(t1).Build()); generatedToTypes.Add(t1); } else { if (generatedSyncSrcTypes.Contains(t1) && generatedSyncTargetTypes.Contains(t2)) { continue; } generatedClass = generatedClass.WithMethod(new SyncMethod(t1, t2).Build()).WithMethod(new SyncMethodAll(t1, t2).Build()); generatedSyncSrcTypes.Add(t1); generatedSyncTargetTypes.Add(t2); } } string str = ClassWriter.Write(generatedClass); context.AddSource(className, SourceText.From(str, Encoding.UTF8)); } else { context.AddSource(stubClass.ClassName, SourceText.From(ClassWriter.Write(stubClass), Encoding.UTF8)); } }
public void Execute(GeneratorExecutionContext context) { var jsonAttributeSource = SourceText.From(GeneratorAttributesText, Encoding.UTF8); context.AddSource("JsonDiscriminatorAttributes.g.cs", jsonAttributeSource); // Retreive the populated receiver if (context.SyntaxReceiver is not JsonDiscriminatorReceiver receiver || receiver.Candidates.Count == 0) { return; } // Retrieve CSharp compilation from context if (context.Compilation is not CSharpCompilation prevCompilation) { return; } // Add new attribute to compilation var options = prevCompilation.SyntaxTrees[0].Options as CSharpParseOptions; var compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(jsonAttributeSource, options)); // Retrieve enum type var enumType = compilation.GetTypeByMetadataName(typeof(System.Enum).FullName); // Define 'fake' json converter attribute { var sb = new IndentedStringBuilder() .AppendLine("#nullable enable") .AppendLine("using System;") .AppendLine("using System.Runtime.Serialization;") .AppendLine("using System.Text.Json;") .AppendLine("using System.Text.Json.Serialization;") .AppendLine() ; using (sb.AppendLine($"namespace Wivuu.Polymorphism").Indent('{')) { using (sb.AppendLine("internal abstract class JsonInheritanceConverter<T> : JsonConverter<T>").Indent('{')) { sb.AppendLine("public abstract string DiscriminatorName { get; }") .AppendLine("public override abstract T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options);") .AppendLine("public override abstract void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options);") ; } } context.AddSource($"JsonInheritanceConverter.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8)); } // Create JsonConverters foreach (var(attr, node, symbol) in receiver.GetDiscriminators(compilation)) { if (GetParentDeclaration(node) is not TypeDeclarationSyntax parentTypeNode) { continue; } if (symbol.ContainingType is not INamedTypeSymbol parentSymbol) { continue; } // Ensure that parent type is not concrete so that we do not cause stack overflow on serialize if (!parentTypeNode.Modifiers.Any(SyntaxKind.AbstractKeyword) && parentSymbol.TypeKind != TypeKind.Interface) { context.ReportDiagnostic( Diagnostic.Create(DiagTypeNotBeConcrete, parentSymbol.Locations[0])); continue; } // Ensure that parent type is partial so we can attach the JsonConverter attribute if (!parentTypeNode.Modifiers.Any(SyntaxKind.PartialKeyword)) { context.ReportDiagnostic( Diagnostic.Create(DiagNotPartial, parentSymbol.Locations[0], parentSymbol.Name)); continue; } // Ensure that the discriminator is an enum var discriminatorType = symbol is IParameterSymbol param ? param.Type as INamedTypeSymbol : symbol is IPropertySymbol prop ? prop.Type as INamedTypeSymbol : default; if (discriminatorType is null || discriminatorType.BaseType?.Equals(enumType, SymbolEqualityComparer.Default) is not true) { context.ReportDiagnostic( Diagnostic.Create(DiagNotEnum, symbol.Locations[0], discriminatorType?.Name ?? symbol.Name)); continue; } // Retrieve fallback attributes for the parent type var fallbacks = new List <(CSharpSyntaxNode, ISymbol)>(receiver.GetFallbacks(compilation, parentSymbol)); if (fallbacks.Count > 1) { foreach (var(_, fbSymbol) in fallbacks) { context.ReportDiagnostic( Diagnostic.Create(DiagOnlyOneFallback, fbSymbol.Locations[0])); } continue; } // Get all possible enum values and corresponding types var classMembers = new List <(string, INamedTypeSymbol, int)>( GetCorrespondingTypes(context, compilation, parentSymbol, discriminatorType, fallbacks.Count == 1)); classMembers.Sort(new SpecificityComparer()); var sb = new IndentedStringBuilder(); sb.AppendLine("#nullable enable") .AppendLine("using System;") .AppendLine("using System.Runtime.Serialization;") .AppendLine("using System.Text.Json;") .AppendLine("using System.Text.Json.Serialization;") .AppendLine() ; var ns = symbol.ContainingType.ContainingNamespace; using (sb.AppendLine($"namespace {ns.ToDisplayString()}").Indent('{')) { // Append known types foreach (var(_, className, _) in classMembers) { sb.AppendLine($"[KnownType(typeof({className.Name}))]"); } // Attribute adding class sb.AppendLine($"[JsonConverter(typeof({parentSymbol.Name}Converter))]"); using (sb.AppendLine($"{parentTypeNode.Modifiers} {parentTypeNode.Keyword.Text} {parentSymbol.Name}").Indent('{')) { // Add static array to house all types using (sb.AppendLine($"private static readonly Type[] _allTypes = ").Indent('{', endCh: "};")) { // Iterate through each member case foreach (var(_, type, _) in classMembers) { sb.AppendLine($"typeof({type}),"); } } // Add static method to get all types sb.AppendLine($"/// <summary>") .AppendLine($"/// Gets all types that are known to the <see cref=\"{parentSymbol.Name}\"/> converter.") .AppendLine($"/// </summary>") .AppendLine($"/// <returns>All types that are known to the <see cref=\"{parentSymbol.Name}\"/> converter.</returns>") .AppendLine("#pragma warning disable CS0109"); using (sb.AppendLine($"public static new Type[] GetAllTypes()").Indent('{')) { sb.AppendLine("return _allTypes;"); } sb.AppendLine("#pragma warning restore CS0109"); // Add static method to get type from discriminator using (sb.AppendLine($"public static Type? GetType({discriminatorType} kind)").Indent('{')) { using (sb.AppendLine($"return kind switch").Indent('{', endCh: "};")) { // Iterate through each member case foreach (var(member, type, _) in classMembers) { sb.AppendLine($"{discriminatorType}.{member} => typeof({type}),"); } if (fallbacks.Count == 1 && fallbacks[0] is var(_, fbSymbol)) { sb.AppendLine($"_ => typeof({fbSymbol.Name})"); } else { sb.AppendLine("_ => default"); } } } } // Converter class using (sb.AppendLine($"internal class {parentSymbol.Name}Converter : Wivuu.Polymorphism.JsonInheritanceConverter<{parentSymbol.Name}>").Indent('{')) { var renderedName = attr?.ConstructorArguments.Length is > 0 ? attr.ConstructorArguments[0].Value?.ToString() : null; // DiscriminatorName property sb.AppendLine($"/// <summary>") .AppendLine($"/// Gets the name of the discriminator property.") .AppendLine($"/// </summary>") .AppendLine($"public override string DiscriminatorName => \"{renderedName ?? symbol.MetadataName}\";") .AppendLine() ; // Read Method using (sb.AppendLine($"public override {parentSymbol.Name}? Read").Indent('(')) sb.AppendLine("ref Utf8JsonReader reader,") .AppendLine("Type typeToConvert,") .AppendLine("JsonSerializerOptions options") ; using (sb.Indent('{')) { // TODO: Determine better way to find in case insensitive way var ident = symbol.MetadataName; var camelIdent = string.Concat(char.ToLowerInvariant(ident[0]), ident.Substring(1)); sb.AppendLine("var deserializedObj = JsonElement.ParseValue(ref reader);") .AppendLine("var discriminator = options.PropertyNamingPolicy == JsonNamingPolicy.CamelCase") .AppendLine($" ? \"{camelIdent}\" : \"{ident}\";") .AppendLine() ; using (sb.AppendLine("if (deserializedObj.TryGetProperty(discriminator, out var property))").Indent('{')) using (sb.AppendLine($"return property.Deserialize<{discriminatorType}>(options)").Indent()) { using (sb.AppendLine("switch").Indent('{', endCh: "};")) { // Iterate through each member case foreach (var(member, type, _) in classMembers) { sb.AppendLine($"{discriminatorType}.{member} => deserializedObj.Deserialize<{type}>(options),") .AppendLine() ; } if (fallbacks.Count == 1 && fallbacks[0] is var(_, fbSymbol)) { sb.AppendLine($"_ => deserializedObj.Deserialize<{fbSymbol.Name}>(options),") .AppendLine() ; } else { sb.AppendLine("_ => default"); } } } sb.AppendLine("return default;"); } sb.AppendLine(); // Write Method using (sb.AppendLine($"public override void Write").Indent('(')) sb.AppendLine("Utf8JsonWriter writer,") .AppendLine($"{parentSymbol.Name} value,") .AppendLine("JsonSerializerOptions options") ; using (sb.Indent('{')) using (sb.AppendLine("switch (value)").Indent('{')) { var i = 0; // Iterate through each member case foreach (var(_, className, _) in classMembers) { ++i; using (sb.AppendLine($"case {className.Name} value{i}:").Indent()) sb.AppendLine($"JsonSerializer.Serialize(writer, value{i}, options);") .AppendLine("break;") ; sb.AppendLine(); } using (sb.AppendLine($"default:").Indent()) if (fallbacks.Count == 1 && fallbacks[0] is var(_, fbSymbol)) { ++i; sb.AppendLine($"if (value is {fbSymbol.Name} value{i})").Indent('{', sb => sb.AppendLine($"JsonSerializer.Serialize(writer, value{i}, options);") .AppendLine("break;") ) .AppendLine("else") .AppendLine($" throw new JsonException($\"{{value.{symbol.MetadataName}}} is not a supported value\");"); ; } else { sb.AppendLine($"throw new JsonException($\"{{value.{symbol.MetadataName}}} is not a supported value\");"); } } } } // Add source context.AddSource($"{parentSymbol.Name}Converter.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8)); } }
private static void GenerateExtensions(GeneratorExecutionContext context) { const string mpWriterExtensions = @" using System.Numerics; using MessagePack; namespace ToolGeneratedExtensions { internal static class MessagePackExtensions { public static void Write(this ref MessagePackWriter writer, Vector2 v) { writer.WriteArrayHeader(2); writer.Write(v.X); writer.Write(v.Y); } public static Vector2 ReadVector2(this ref MessagePackReader reader) { reader.ReadArrayHeader(); return new Vector2(reader.ReadSingle(), reader.ReadSingle()); } public static void Write(this ref MessagePackWriter writer, in Vector3 v) { writer.WriteArrayHeader(3); writer.Write(v.X); writer.Write(v.Y); writer.Write(v.Z); } public static Vector3 ReadVector3(this ref MessagePackReader reader) { reader.ReadArrayHeader(); return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } public static void Write(this ref MessagePackWriter writer, in Vector4 v) { writer.WriteArrayHeader(4); writer.Write(v.X); writer.Write(v.Y); writer.Write(v.Z); writer.Write(v.W); } public static Vector4 ReadVector4(this ref MessagePackReader reader) { reader.ReadArrayHeader(); return new Vector4( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() ); } public static void Write(this ref MessagePackWriter writer, in Matrix4x4 m) { writer.WriteArrayHeader(16); writer.Write(m.M11); writer.Write(m.M12); writer.Write(m.M13); writer.Write(m.M14); writer.Write(m.M21); writer.Write(m.M22); writer.Write(m.M23); writer.Write(m.M24); writer.Write(m.M31); writer.Write(m.M32); writer.Write(m.M33); writer.Write(m.M34); writer.Write(m.M41); writer.Write(m.M42); writer.Write(m.M43); writer.Write(m.M44); } public static Matrix4x4 ReadMatrix4x4(this ref MessagePackReader reader) { reader.ReadArrayHeader(); return new Matrix4x4( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() ); } } }"; context.AddSource("MessagePackExtensions.cs", SourceText.From(mpWriterExtensions, Encoding.UTF8)); }
private void GenerateCode(GeneratorExecutionContext context, TypeDeclarationSyntax tds, Type attributeType) { // Field symbol var symbol = context.ParseSyntaxNode <INamedTypeSymbol>(tds); if (symbol == null || context.CancellationToken.IsCancellationRequested) { return; } // Attribute data var attributeData = symbol.GetAttributeData(attributeType.FullName); // Snake case var snakeCase = attributeData?.GetValue <bool>(nameof(AutoToParametersAttribute.SnakeCase)); // Name space and class name var(ns, className) = (symbol.ContainingNamespace.ToDisplayString(), symbol.Name); // Keyword var keyword = tds.Keyword.ToString(); // Is Public var isPublic = tds.HasToken(SyntaxKind.PublicKeyword); // Name var name = tds.Identifier.ToString(); // Inheritance var externals = new List <string>(); // Body var body = GenerateBody(context, tds, snakeCase.GetValueOrDefault(), externals, ns); if (context.CancellationToken.IsCancellationRequested) { return; } externals.Add($"com.etsoo.Utils.Serialization.IDictionaryParser<{name}>"); // Source code var source = $@"#nullable enable using com.etsoo.Utils.String; using System; using System.Collections.Generic; using System.Linq; namespace {ns} {{ {(isPublic ? "public" : "internal")} partial {keyword} {className} : {string.Join(", ", externals)} {{ public static {name} Create(StringKeyDictionaryObject dic) {{ return new {name} {body}; }} }} }} "; context.AddSource($"{ns}.{className}.Dictionary.Generated.cs", SourceText.From(source, Encoding.UTF8)); }
public virtual void Execute(GeneratorExecutionContext context) { context.AddSource("EmptyGeneratedFile", string.Empty); }
public void Execute(GeneratorExecutionContext context) { context.AddSource(this._hintName, SourceText.From(_content, Encoding.UTF8)); }
public void Execute(GeneratorExecutionContext context) { //#if DEBUG // if (!Debugger.IsAttached) // Debugger.Launch(); //#endif ICollection <string> typeNames = context.Compilation.Assembly.TypeNames; HashSet <string> topicNames = new HashSet <string>(StringComparer.Ordinal); foreach (string typeName in typeNames) { INamedTypeSymbol p = context.Compilation.GetSymbolsWithName(typeName).FirstOrDefault() as INamedTypeSymbol; if (p == null) { continue; } if (!p.AllInterfaces.Any(x => x.Name == "IHassDiscoveryDocument")) { continue; } List <ISymbol> props = p.GetMembers() .Where(s => s.Name.EndsWith("Topic") && s.Kind == SymbolKind.Property) .ToList(); foreach (ISymbol symbol in props) { string name = symbol.Name.Replace("Topic", ""); topicNames.Add(name); } } // Remove some names topicNames.Remove(""); topicNames.Remove("Publish"); StringBuilder sb = new StringBuilder(); sb.AppendLine("using System.Runtime.Serialization;"); sb.AppendLine(""); sb.AppendLine("namespace MBW.HassMQTT.DiscoveryModels.Enum"); sb.AppendLine("{"); sb.AppendLine(" public enum HassTopicKind"); sb.AppendLine(" {"); foreach (string topicName in topicNames.OrderBy(s => s)) { string value = Regex.Replace(topicName, "[A-Z]", match => { if (match.Index == 0) { return(match.Value.ToLower()); } return("_" + match.Value.ToLower()); }); sb.AppendLine($" [EnumMember(Value = \"{value}\")]"); sb.AppendLine($" {topicName},"); } sb.AppendLine(" }"); sb.AppendLine("}"); context.AddSource("HassTopicKind_generated.cs", SourceText.From(sb.ToString(), Encoding.UTF8)); }