From 9461773d028766ddf4593fcfa0705f235d64b9ec Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Sun, 12 Jun 2022 21:21:29 -0500 Subject: [PATCH] Added initial MarkupDataMapping codegen --- Tests/SimpleDebugClient/Program.cs | 13 +++- UIX/Microsoft/Iris/Debug/DebugSettings.cs | 5 ++ .../Iris/Markup/CompiledMarkupLoader.cs | 5 ++ .../Iris/Markup/MarkupDataMapping.cs | 74 ++++++++++++++++++- UIX/UIX.csproj | 2 + 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/Tests/SimpleDebugClient/Program.cs b/Tests/SimpleDebugClient/Program.cs index b61b4e1..1389445 100644 --- a/Tests/SimpleDebugClient/Program.cs +++ b/Tests/SimpleDebugClient/Program.cs @@ -7,7 +7,18 @@ namespace SimpleDebugClient static void Main(string[] args) { Bridge bridge = new(OwlCore.Remoting.RemotingMode.Client); - while (true) ; + bridge.DispatcherStep += Bridge_DispatcherStep; + bridge.InterpreterStep += Bridge_InterpreterStep; + } + + private static void Bridge_DispatcherStep(string obj) + { + Console.WriteLine(obj); + } + + private static void Bridge_InterpreterStep(object? sender, Microsoft.Iris.Debug.Data.InterpreterEntry e) + { + Console.WriteLine(e); } } } \ No newline at end of file diff --git a/UIX/Microsoft/Iris/Debug/DebugSettings.cs b/UIX/Microsoft/Iris/Debug/DebugSettings.cs index 7e4e49f..f828099 100644 --- a/UIX/Microsoft/Iris/Debug/DebugSettings.cs +++ b/UIX/Microsoft/Iris/Debug/DebugSettings.cs @@ -9,6 +9,11 @@ namespace Microsoft.Iris.Debug public List DecompileResults { get; } = new List(); public TraceSettings TraceSettings { get; } = TraceSettings.Current; +#if OPENZUNE + public bool GenerateDataMappingModels { get; set; } = true; + public List DataMappingModels { get; } = new List(); +#endif + public Bridge Bridge { get; } = #if OPENZUNE new(OwlCore.Remoting.RemotingMode.Host); diff --git a/UIX/Microsoft/Iris/Markup/CompiledMarkupLoader.cs b/UIX/Microsoft/Iris/Markup/CompiledMarkupLoader.cs index 9dee442..e0677c0 100644 --- a/UIX/Microsoft/Iris/Markup/CompiledMarkupLoader.cs +++ b/UIX/Microsoft/Iris/Markup/CompiledMarkupLoader.cs @@ -495,6 +495,11 @@ namespace Microsoft.Iris.Markup markupDataMapping.Mappings[index3] = dataMappingEntry; } dataMappingsTable[index1] = markupDataMapping; + +#if OPENZUNE + if (Application.DebugSettings.GenerateDataMappingModels) + Application.DebugSettings.DataMappingModels.Add(markupDataMapping.GenerateModelCode()); +#endif } _loadResultTarget.SetDataMappingsTable(dataMappingsTable); } diff --git a/UIX/Microsoft/Iris/Markup/MarkupDataMapping.cs b/UIX/Microsoft/Iris/Markup/MarkupDataMapping.cs index 8a9b10b..333bbb3 100644 --- a/UIX/Microsoft/Iris/Markup/MarkupDataMapping.cs +++ b/UIX/Microsoft/Iris/Markup/MarkupDataMapping.cs @@ -4,6 +4,15 @@ // MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11 // Assembly location: C:\Program Files\Zune\UIX.dll +#if OPENZUNE +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Options; +#endif + namespace Microsoft.Iris.Markup { internal class MarkupDataMapping @@ -40,6 +49,69 @@ namespace Microsoft.Iris.Markup set => _assemblyDataProviderCookie = value; } - public override string ToString() => string.Format("({0}, {1})", _provider, _targetType); + public override string ToString() => $"({_provider}, {_targetType})"; + +#if OPENZUNE + /// + /// Generates C# code for a plain-old CLR object (POCO) that can + /// be used to serialize and deserialize the data this mapping + /// represents. + /// + public string GenerateModelCode() + { + CompilationUnitSyntax cu = SyntaxFactory.CompilationUnit() + .AddUsings + ( + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("System")) + ); + + NamespaceDeclarationSyntax localNamespace = SyntaxFactory.NamespaceDeclaration( + SyntaxFactory.IdentifierName("Zune.Xml")); + + ClassDeclarationSyntax modelClass = SyntaxFactory.ClassDeclaration(TargetType.Name) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); + + System.Collections.Generic.List members = new(Mappings.Length); + foreach (var mapping in Mappings) + { + var propertyType = SyntaxFactory.ParseTypeName(mapping.Property.PropertyType.Name); + var property = SyntaxFactory.PropertyDeclaration(propertyType, mapping.Property.Name) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); + + if (mapping.Source != null) + { + string elementName = mapping.Source[1..]; + var elementNameAttr = SyntaxFactory.AttributeArgument( + SyntaxFactory.ParseExpression($"ElementName = {elementName}")); + + var attributes = SyntaxFactory.AttributeList().AddAttributes + ( + SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("XmlElement"), + SyntaxFactory.AttributeArgumentList().AddArguments(elementNameAttr)) + ); + + property = property.AddAttributeLists(attributes); + } + + members.Add(property); + } + modelClass = modelClass.AddMembers(members.ToArray()); + + // Add to file root + localNamespace = localNamespace.AddMembers(modelClass); + cu = cu.AddMembers(localNamespace); + + // Format file + AdhocWorkspace cw = new(); + OptionSet options = cw.Options; + cw.Options.WithChangedOption(CSharpFormattingOptions.IndentBraces, true); + SyntaxNode formattedNode = Formatter.Format(cu, cw, options); + + // Write to string + using System.IO.StringWriter writer = new(); + formattedNode.WriteTo(writer); + return writer.ToString(); + } +#endif } } diff --git a/UIX/UIX.csproj b/UIX/UIX.csproj index 1bb5f20..cf13f21 100644 --- a/UIX/UIX.csproj +++ b/UIX/UIX.csproj @@ -44,6 +44,8 @@ + +