General purpose pluggable XAML compiler with no runtime dependencies.
General purpose pluggable XAML compiler with no runtime dependencies. Currently being used by Avalonia project as the XAML engine.
The compiler isn't tied to Avalonia in any way, shape or form and can be used for any purposes by configuring
XamlLanguageTypeMappingsto match the needs of your particular framework. Further customization can be done by AST manipulations, see examples of those in Avalonia repository.
[DeferredContent]get assigned a
Funcdelegate which emits child nodes (can be customized, see DeferredContentTests)
static T Parse(string, [IFormatProvider])method (e. g.
int,
double,
TimeSpan, etc)
[Content]attribute both for direct content and for collections
Binding)
Tis anything that's not
System.Object):
cs T ProvideValue(); T ProvideValue(IServiceProvider provider); object ProvideValue(); object ProvideValue(IServiceProvider provider);If strongly typed markup extension overload is available, it's used to avoid unnecessary casts and boxing
ldnull)
ldtoken+
Type.FromRuntimeHandle)
call get_PropName), fields (
ldsfld), constants/enums (
ldc_*/
ldstr)
Runtime xmlns information via
IXamlXmlNamespaceInfoProvider(provides
Dictionary)
xml:space Handling in XAML (automatically via XmlReader)
Event handlers from codebehind
The flow looks like this:
1) Parse XAML into some basic AST (we can use different language markup parser at this point, like C#/VB in Roslyn) 2) Transform AST via visitors. At this stage types get resolved, property values get transformed either in setting properties or collection access, etc 3) Emit IL code
Features marked with [dontneed] aren't required for the Avalonia project, but might be implemented later if the need arises. Features marked with [opt] are considered optional and will be implemented after non-optional features
These are questinable due to heavy reliance on reflection: - IXamlTypeResolver (can be implemented in runtime via
IXamlXmlNamespaceInfoProviderV1) [dontneed] - IXamlNameResolver (probably without forward references) [dontneed] - IXamlNamespaceResolver [dontneed]
These are framework-specific and can be implemented via custom transformers/emitters or custom IServiceProvider - x:Property Directive - x:Uid Directive - x:XData Intrinsic XAML Type - x:Shared Attribute - x:Class Directive - x:Subclass Directive - x:ClassModifier Directive - x:FieldModifier Directive - x:Member Directive - x:Members Directive
Future: x:Code Intrinsic XAML Type (probably use Roslyn to inline C# code)
TypeConverter's,
DeferredContent) inside of them
RootObjectcould be saved in a closure, right deferred content builder attempts to extract it from passed
IServiceProvider