Static analysis of Silverlight XAML: Basic concepts

Silverlight has APIs that support quite a variety of client-side APIs. But one area where the API is rather thin in Silverlight is interacting with XAML as a format, and discovering or changing how the Silverlight XAML parser works in the client runtime. Without such API, it is not really practical to use the Silverlight client API for many XAML-related tasks, and in particular static analysis of XAML with a Silverlight client-centric application is difficult and limited.

However, with some of the architectural improvements in the Silverlight XAML parser that were made in version 4, combined with some. NET Framework APIs (the full framework, not the Silverlight subset), static analysis of Silverlight XAML is definitely possible. To do this, you'll be writing a .NET Framework executable that runs on a Windows desktop, not a Silverlight application, but your .NET app will have the necessary information to treat the XAML very similar to how the Silverlight XAML parser and the overall Silverlight development environment would treat that XAML.

The two pieces that you need beyond the typical setup for Silverlight development are: .NET Framework version 4, and an out-of-band Microsoft release called the XAML Toolkit.

.NET Framework version 4

You probably already have this framework. If you are using a Windows 7 machine, you already have it. If you are using Visual Studio 10, you already have it too. On the outside chance you don’t already have .NET Framework version 4, you can use sources like the site to install it. You’ll probably need it anyway if you are doing any other substantial .NET development.

Part of .NET Framework version 4 is an assembly called System.Xaml. This one piece is why you really need the full framework installed (and the version 4 particularly, because System.Xaml did not exist in older frameworks).  The notable parts of System.Xaml that are important for static analysis are:

* A generalized and extensible concept of a XAML reader, plus at least one practical implementation.

* A generalized and extensible concept of a XAML writer, plus at least one practical implementation.

* A XAML type system, so that readers and writers can transmit a conceptualized XAML to each other, and can abstract away issues such as the format or encoding of any original XAML-as-text source, its syntax peculiarities, etc. In particular, there is a XamlType object that represents a type concept as it relates to XAML, and a XamlMember object that represents a member, plus many supporting types and attributes.

* A way to keep the readers and writers apart on purpose, so that a program can examine the XAML purely in the domain of XAML as a language. System.Xaml provides this through a concept of a XAML node stream.

Why is this last point of separating readers and writers important? Because this makes it possible to parse bad XAML, even really badly invalid XAML, and still tell you something useful about it. Using the separated readers and writers, you can hang the reading/parsing result onto enough of a structure to point out specific problems, rather than just having a parser report a Global Fail (which is unfortunately and all too often a typical client-side XAML debugging experience).

For example, you could read in XAML that has failed type-mappings or other significant flaws, which would bring the whole house down if you tried to load it into a Silverlight runtime client. You could then treat that XAML piece by piece as a debug or tooling experience, and perhaps note or deal with such issues while still making the actual corrections to the XAML types in situ. The ungainly alternative (as many early Silverlight XAML tools had no choice but to do) is to reload a changed XML source every time you make even the most trivial change. Clearly, that’s not a good enough basis to write any serious tools or analysis.

In contrast to the full framework, the Silverlight core assembly set does not have a direct equivalent to System.Xaml. Some of the same code is there, but is specified as an internal type in the Silverlight version. Also, large parts of the Silverlight XAML parser implementation are not managed code. Nevertheless, the Silverlight XAML parser has an understanding of the various XAML type system conceptualizations that are formalized by the managed API in the System.Xaml assembly.

As useful as System.Xaml API is as a starting point, there is one critical piece missing in what I’ve described to you so far. System.Xaml does not inherently know anything about how a Silverlight XAML parser really behaves. (System.Xaml has a default and generalized sense of CLR-to-XAML mapping, but that generalized model misses many important framework-specific concepts; for instance, how styles work.) To get to that, you need a practical implementation of something that System.Xaml is expecting to get from individual frameworks – this information is conveyed to System.Xaml subsystems by something called a XAML schema context.

XAML Toolkit

As mentioned, the XAML Toolkit is an out-of-band release. It has assemblies that are built on .NET Framework 4. But the code in XAML Toolkit is all still at a CTP level of support. You can get the XAML Toolkit, and find out more about its level of support, here:

The main piece that comes with the XAML Toolkit that is relevant for Silverlight static XAML analysis is the Silverlight XAML schema context. The schema context does not ship with the Silverlight client run time. This is partly because the runtime really doesn't need it; the XAML schema context accurately describes what Silverlight does, but doesn't really CONTROL what Silverlight does, when it comes to its XAML implementation or its parser.

So what?

OK I’ve described the WHAT, now here is the WHY (or perhaps, more cheekily, the SO WHAT?)

To show you a quick and already existing example, check out Rob Relyea’s BindingFinder utility. This utility is a good illustration of simple yet powerful analysis of XAML you can perform by writing against System.Xaml API using the specific framework’s schema context for help. This particular utility writes out a report of every {Binding} usage it finds in XAML. This isn’t just done by text search (remember, you can specify <Binding …/> too, or several other syntax variations). Rather, the utility finds the references to the specific Binding markup extension through any possible syntax, identifies the binding by its XAML type system representation, and reports the specifics of each binding.

Probably the most interesting frontier for Silverlight XAML analysis and tooling using the XAML toolkit APIs is creating a pipeline for XAML migration from one platform to another. The most obvious example scenario is migrating a XAML UI that was originally created for WPF to Silverlight. In particular, this is relevant for XAML content that is largely design-based, things like the generic.xaml of a sophisticated custom control set. Silverlight and WPF XAML are pretty close, but depending on your project, you might encounter issues where Silverlight won’t support a particular construct. Sometimes these are really just platform differences surfaced in XAML. An example of this is that Silverlight doesn’t support {DynamicResource}. Other times there are differences that are arguably differences in the language interpretation or general type mapping; an example of this is that Silverlight has a few structures that can’t support attributes on object element usages (requiring initialization syntax as a workaround).

When I have some more time to play with some of this stuff myself, I intend to follow up on this post with a sample-grade project that tackles just one such feature-migration path. For (possible) example: detect all {DynamicResource} usages in page scope made in WPF XAML, change them to {StaticResource} references against a built-up merged dictionary at application level for the Silverlight XAML. Also will discuss some related static analysis concepts, such as FxCop for XAML (which is enabled by another part of the XAML Toolkit).

Comments (0)

Skip to main content