Talkin’ ‘bout my generation: How the Uno Platform generates code, part 1 — Under The hood
Tags: underthehood
Published: 2019-10-11 15:21:09

---
title: Talkin’ ‘bout my generation: How the Uno Platform generates code, part 1 — Under The hood
published: true
tags: Under The Hood
canonical_url: https://platform.uno/talkin-bout-my-generation-how-the-uno-platform-generates-code-part-1%e2%80%8a-%e2%80%8aunder-the-hood/
---

<section>
<div>
<div>
<p id="3c84">In previous articles, we’ve covered how the <a href="https://platform.uno/" target="_blank" rel="nofollow noopener" data-href="https://platform.uno/">Uno Platform</a> takes a visual tree defined in the <a href="https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/xaml-overview" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/xaml-overview">XAML</a> markup language and creates it on iOS, Android, and WebAssembly. In this article I want to dive into a key intermediate step: how the XAML is parsed and mapped to generated C# code. In part 2, we’ll look at a few other ways in which Uno leverages code generation to make the wheels turn.</p>
<h3 id="06f4">Parsing XAML</h3>
<p id="4627">XAML stands for eXtensible Application Markup Language. It’s an XML-based syntax. Although it can be used to describe <a href="https://docs.microsoft.com/en-us/dotnet/framework/windows-workflow-foundation/serializing-workflows-and-activities-to-and-from-xaml" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/dotnet/framework/windows-workflow-foundation/serializing-workflows-and-activities-to-and-from-xaml">pretty much anything</a>, it’s geared toward describing the structure of an application. It was first used in <a href="https://en.wikipedia.org/wiki/Windows_Presentation_Foundation" target="_blank" rel="nofollow noopener" data-href="https://en.wikipedia.org/wiki/Windows_Presentation_Foundation">Windows Presentation Foundation</a>, and since then has been used (with minor syntactic differences) in a number of contexts, including Silverlight (RIP), WinRT, Xamarin Forms, and the Universal Windows Platform.</p>
<p id="0f42">XAML hits a sweet spot: it’s human readable, expressive, and sufficiently structured to support design tools like <a href="https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-ui-by-using-blend-for-visual-studio?view=vs-2017" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-ui-by-using-blend-for-visual-studio?view=vs-2017">Blend</a> and <a href="https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-ui-by-using-xaml-designer-in-visual-studio?view=vs-2017" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/visualstudio/designers/creating-a-ui-by-using-xaml-designer-in-visual-studio?view=vs-2017">XAML Designer</a>. One nice feature is that it can be seamlessly intermingled with C# via <a href="https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/code-behind-and-xaml-in-wpf" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/code-behind-and-xaml-in-wpf">code-behind</a> files.</p>
<p id="1642">To tap into that power, Uno needs to be able to read a XAML file and convert it into compileable C# code.</p>
<p id="9063">The first step is to parse the file into a Xaml object tree, using the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.xaml?view=netframework-4.7.2" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/dotnet/api/system.xaml?view=netframework-4.7.2">System.Xaml</a>namespace.</p>
<p id="6c05">Next, the Xaml object tree is processed into a C# class definition. The bulk of the heavy lifting is done in the mammoth <a href="https://github.com/nventive/Uno/blob/master/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs" target="_blank" rel="nofollow noopener" data-href="https://github.com/nventive/Uno/blob/master/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs">XamlFileGenerator</a> class. We lean on the <a href="https://github.com/dotnet/roslyn" target="_blank" rel="nofollow noopener" data-href="https://github.com/dotnet/roslyn">Microsoft.CodeAnalysis API</a> here (aka ‘Roslyn’) to match types used in XAML to types defined in the app assembly or its dependencies. The output is saved to a generated file.</p>
<p id="ef04">All this happens behind the scenes whenever you build an Uno head.</p>
<h3 id="c894">The end result</h3>
<p id="1380">Let’s look at a concrete example. This is part of the markup we put in <code>MainPage.xaml</code> in a previous article:</p>
<pre id="f991">&lt;StackPanel&gt; 
        &lt;TextBlock x:Name="ClickTextBlock" 
                   Text="Button wasn't clicked yet" /&gt; 
        &lt;Button Content="Click me" 
                Click="Button_Click" /&gt; 
    &lt;/StackPanel&gt;</pre>
<p id="5c5d">The generated output can be found in the ‘obj’ folder under the project head.</p>
<p id="f329">
</p>
<div>
<div></div>
<div data-image-id="0*lGYiCBWwMK-g_Fk9.png" data-width="515" data-height="559" data-scroll="native"><img src="https://cdn-images-1.medium.com/max/800/0*lGYiCBWwMK-g_Fk9.png" data-src="https://cdn-images-1.medium.com/max/800/0*lGYiCBWwMK-g_Fk9.png"></div>
</div>

<p id="da97"><em>The code file generated from MainPage.xaml.</em></p>
<p id="a7e3">This is a part of the generated code, showing the output for the XAML snippet above:</p>
<pre id="c2fb">public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page 
    { 
        private void InitializeComponent() 
        { 
            var nameScope = new global::Windows.UI.Xaml.NameScope(); 
            NameScope.SetNameScope(this, nameScope); 
            // Source ..\..\..\..\..\..\UnoExtTestbed.Shared\MainPage.xaml (Line 1:2) 
            Content = new global::Windows.UI.Xaml.Controls.StackPanel 
            { 
                // Source ..\..\..\..\..\..\UnoExtTestbed.Shared\MainPage.xaml (Line 8:3) 
                Children =  
                { 
                    new global::Windows.UI.Xaml.Controls.TextBlock 
                    { 
                        Name = "ClickTextBlock", 
                        Text = "Button wasn't clicked yet", 
                        // Source ..\..\..\..\..\..\UnoExtTestbed.Shared\MainPage.xaml (Line 9:4) 
                    } 
                    .MainPage_05a03e67d6a6581089c5d12899278d61_XamlApply((MainPage_05a03e67d6a6581089c5d12899278d61XamlApplyExtensions.XamlApplyHandler0)(c0 =&gt;  
                    { 
                        nameScope.RegisterName("ClickTextBlock", c0); 
                        this.ClickTextBlock = c0; 
                    } 
                    )) 
                    , 
                    new global::Windows.UI.Xaml.Controls.Button 
                    { 
                        Content = @"Click me", 
                        // Source ..\..\..\..\..\..\UnoExtTestbed.Shared\MainPage.xaml (Line 11:4) 
                    } 
                    .MainPage_05a03e67d6a6581089c5d12899278d61_XamlApply((MainPage_05a03e67d6a6581089c5d12899278d61XamlApplyExtensions.XamlApplyHandler1)(c1 =&gt;  
                    { 
                        c1.Click += Button_Click; 
                    } 
                    )) 
                    , 
                } 
            }</pre>
<p id="2fe3">What a mouthful! Generated code tends to be optimized for machine readability, rather than for human readability. For example, the explicit casts to <code>XamlApplyHandler</code> were added when we found that the compiler was having to do a lot of computationally-expensive type inference. That one change doubled the compilation speed for large XAML files.</p>
<p id="050c">In the normal course of Uno development you don’t need to look at code generated from XAML or even know that it’s there, though occasionally it’s useful to take a peek when debugging.</p>
<p id="f9a9">Recall that the <code>Button_Click</code> event is defined in <a href="https://medium.com/@unoplatform/pushing-the-right-buttons-how-uno-implements-views-under-the-hood-a5e93ea86688#the-number-goes-up" target="_blank" rel="nofollow noopener" data-href="https://medium.com/@unoplatform/pushing-the-right-buttons-how-uno-implements-views-under-the-hood-a5e93ea86688#the-number-goes-up">the code-behind</a> for MainPage. As far as the compiler is concerned, both the authored and generated files are just <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods">partial definitions</a> of the same class.</p>
<p id="4326">One last fun fact: when building on MacOS using <a href="https://visualstudio.microsoft.com/vs/mac/" target="_blank" rel="nofollow noopener" data-href="https://visualstudio.microsoft.com/vs/mac/">Visual Studio for Mac</a>(which Uno tentatively supports in preview), Uno uses an internal port in place of the System.Xaml namespace which isn’t available on Mac. The same code backs Uno’s support for runtime Xaml interpretation via <a href="https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.markup.xamlreader" target="_blank" rel="nofollow noopener" data-href="https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.markup.xamlreader">Windows.UI.Xaml.Markup.XamlReader</a>, which is used in the <a href="https://github.com/nventive/Uno.Playground/blob/master/src/Uno.Playground.Shared/Samples/Playground.xaml" target="_blank" rel="nofollow noopener" data-href="https://github.com/nventive/Uno.Playground/blob/master/src/Uno.Playground.Shared/Samples/Playground.xaml">interactive mode</a>of the <a href="https://github.com/nventive/Uno.Playground" target="_blank" rel="nofollow noopener" data-href="https://github.com/nventive/Uno.Playground">Uno Gallery app</a> and <a href="https://playground.platform.uno/" target="_blank" rel="nofollow noopener" data-href="https://playground.platform.uno/">Uno.Playground website</a>.</p>
</div>
<p> </p>
</div>
</section><section>
<div></div>
<div>
<div>
<p id="329a">
</p>
<div></div>

</div>
</div>
</section>

The post [Talkin’ ‘bout my generation: How the Uno Platform generates code, part 1 — Under The hood](https://platform.uno/talkin-bout-my-generation-how-the-uno-platform-generates-code-part-1%e2%80%8a-%e2%80%8aunder-the-hood/) appeared first on [Uno Platform](https://platform.uno).