Browse Source

WIP2

xamlil-debug-info
Nikita Tsukanov 8 years ago
parent
commit
58de2aaac0
  1. 16
      samples/ControlCatalog/MainView.xaml.cs
  2. 33
      samples/ControlCatalog/MainWindow.xaml
  3. 21
      src/Avalonia.Base/AvaloniaProperty.cs
  4. 16
      src/Markup/Avalonia.Markup.Xaml/Extensions.cs
  5. 33
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
  6. 5
      src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs
  7. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs
  8. 3
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  9. 42
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs
  10. 7
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs
  11. 7
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  12. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
  13. 2
      src/Markup/Avalonia.Markup/Data/MultiBinding.cs

16
samples/ControlCatalog/MainView.xaml.cs

@ -1,8 +1,11 @@
using System;
using System.Collections; using System.Collections;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Markup.Xaml.Styling; using Avalonia.Markup.Xaml.Styling;
using Avalonia.Markup.Xaml.XamlIl;
using Avalonia.Platform; using Avalonia.Platform;
using ControlCatalog.Pages; using ControlCatalog.Pages;
@ -28,8 +31,20 @@ namespace ControlCatalog
}); });
} }
/*
var light = AvaloniaXamlLoader.Parse<StyleInclude>(@"<StyleInclude xmlns='https://github.com/avaloniaui' Source='resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default'/>"); var light = AvaloniaXamlLoader.Parse<StyleInclude>(@"<StyleInclude xmlns='https://github.com/avaloniaui' Source='resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default'/>");
var dark = AvaloniaXamlLoader.Parse<StyleInclude>(@"<StyleInclude xmlns='https://github.com/avaloniaui' Source='resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default'/>"); var dark = AvaloniaXamlLoader.Parse<StyleInclude>(@"<StyleInclude xmlns='https://github.com/avaloniaui' Source='resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default'/>");
*/
var light = new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{
Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default")
};
var dark = new StyleInclude(new Uri("resm:Styles?assembly=ControlCatalog"))
{
Source = new Uri("resm:Avalonia.Themes.Default.Accents.BaseDark.xaml?assembly=Avalonia.Themes.Default")
};
var themes = this.Find<DropDown>("Themes"); var themes = this.Find<DropDown>("Themes");
themes.SelectionChanged += (sender, e) => themes.SelectionChanged += (sender, e) =>
{ {
@ -49,6 +64,7 @@ namespace ControlCatalog
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
AvaloniaXamlIlRuntimeCompiler.DumpRuntimeCompilationResults();
} }
} }
} }

33
samples/ControlCatalog/MainWindow.xaml

@ -1,8 +1,39 @@
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300" <Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
xmlns:pages="clr-namespace:ControlCatalog.Pages"
Title="Avalonia Control Gallery" Title="Avalonia Control Gallery"
Icon="/Assets/test_icon.ico" Icon="/Assets/test_icon.ico"
xmlns:local="clr-namespace:ControlCatalog" xmlns:local="clr-namespace:ControlCatalog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ControlCatalog.MainWindow"> x:Class="ControlCatalog.MainWindow">
<local:MainView/> <!--<local:MainView/>-->
<ScrollViewer>
<StackPanel>
<pages:AutoCompleteBoxPage/>
<pages:BorderPage/>
<pages:ButtonPage/>
<pages:ButtonSpinnerPage/>
<pages:CalendarPage/>
<pages:CanvasPage/>
<pages:CarouselPage/>
<pages:CheckBoxPage/>
<pages:ContextMenuPage/>
<pages:DatePickerPage/>
<pages:DragAndDropPage/>
<pages:DropDownPage/>
<pages:ExpanderPage/>
<pages:ImagePage/>
<pages:LayoutTransformControlPage/>
<pages:ListBoxPage/>
<pages:MenuPage/>
<pages:NumericUpDownPage/>
<pages:ProgressBarPage/>
<pages:RadioButtonPage/>
<pages:SliderPage/>
<pages:TabControlPage/>
<pages:TextBoxPage/>
<pages:ToolTipPage/>
<pages:TreeViewPage/>
<pages:ViewboxPage/>
</StackPanel>
</ScrollViewer>
</Window> </Window>

21
src/Avalonia.Base/AvaloniaProperty.cs

@ -19,7 +19,7 @@ namespace Avalonia
/// <summary> /// <summary>
/// Represents an unset property value. /// Represents an unset property value.
/// </summary> /// </summary>
public static readonly object UnsetValue = new Unset(); public static readonly object UnsetValue = new UnsetValueType();
private static int s_nextId; private static int s_nextId;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _initialized; private readonly Subject<AvaloniaPropertyChangedEventArgs> _initialized;
@ -546,16 +546,17 @@ namespace Avalonia
} }
} }
}
/// <summary>
/// Class representing the <see cref="UnsetValue"/>.
/// </summary>
public class UnsetValueType
{
/// <summary> /// <summary>
/// Class representing the <see cref="UnsetValue"/>. /// Returns the string representation of the <see cref="UnsetValue"/>.
/// </summary> /// </summary>
private class Unset /// <returns>The string "(unset)".</returns>
{ public override string ToString() => "(unset)";
/// <summary>
/// Returns the string representation of the <see cref="UnsetValue"/>.
/// </summary>
/// <returns>The string "(unset)".</returns>
public override string ToString() => "(unset)";
}
} }
} }

16
src/Markup/Avalonia.Markup.Xaml/Extensions.cs

@ -1,14 +1,16 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Avalonia.Markup.Xaml.XamlIl.Runtime; using Avalonia.Markup.Xaml.XamlIl.Runtime;
using Portable.Xaml;
using Portable.Xaml.Markup; using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml namespace Avalonia.Markup.Xaml
{ {
internal static class Extensions internal static class Extensions
{ {
public static T GetService<T>(this IServiceProvider sp) => (T)sp.GetService(typeof(T)); public static T GetService<T>(this IServiceProvider sp) => (T)sp?.GetService(typeof(T));
public static Uri GetContextBaseUri(this IServiceProvider ctx) public static Uri GetContextBaseUri(this IServiceProvider ctx)
@ -37,6 +39,18 @@ namespace Avalonia.Markup.Xaml
(ITypeDescriptorContext)ctx); (ITypeDescriptorContext)ctx);
} }
public static IEnumerable<T> GetParents<T>(this IServiceProvider sp)
{
var stack = sp.GetService<IAvaloniaXamlIlParentStackProvider>();
if (stack != null)
return stack.Parents.OfType<T>();
var context = (ITypeDescriptorContext)sp;
var schemaContext = context.GetService<IXamlSchemaContextProvider>().SchemaContext;
var ambientProvider = context.GetService<IAmbientProvider>();
return ambientProvider.GetAllAmbientValues(schemaContext.GetXamlType(typeof(T))).OfType<T>();
}
public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type) public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type)
{ {
var tr = ctx.GetService<IXamlTypeResolver>(); var tr = ctx.GetService<IXamlTypeResolver>();

33
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs

@ -28,36 +28,31 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public override object ProvideValue(IServiceProvider serviceProvider) public override object ProvideValue(IServiceProvider serviceProvider)
{ {
var context = (ITypeDescriptorContext)serviceProvider;
var schemaContext = context.GetService<IXamlSchemaContextProvider>().SchemaContext;
var ambientProvider = context.GetService<IAmbientProvider>();
var resourceProviderType = schemaContext.GetXamlType(typeof(IResourceNode));
var ambientValues = ambientProvider.GetAllAmbientValues(resourceProviderType);
// Look upwards though the ambient context for IResourceProviders which might be able // Look upwards though the ambient context for IResourceProviders which might be able
// to give us the resource. // to give us the resource.
foreach (var ambientValue in ambientValues) foreach (var resourceProvider in serviceProvider.GetParents<IResourceNode>())
{ {
// We override XamlType.CanAssignTo in BindingXamlType so the results we get back // We override XamlType.CanAssignTo in BindingXamlType so the results we get back
// from GetAllAmbientValues aren't necessarily of the correct type. // from GetAllAmbientValues aren't necessarily of the correct type.
if (ambientValue is IResourceNode resourceProvider)
if (resourceProvider is IControl control && control.StylingParent != null)
{ {
if (resourceProvider is IControl control && control.StylingParent != null) // If we've got to a control that has a StylingParent then it's probably
{ // a top level control and its StylingParent is pointing to the global
// If we've got to a control that has a StylingParent then it's probably // styles. If this is case just do a FindResource on it.
// a top level control and its StylingParent is pointing to the global return control.FindResource(ResourceKey);
// styles. If this is case just do a FindResource on it.
return control.FindResource(ResourceKey);
}
else if (resourceProvider.TryGetResource(ResourceKey, out var value))
{
return value;
}
} }
else if (resourceProvider.TryGetResource(ResourceKey, out var value))
{
return value;
}
} }
// The resource still hasn't been found, so add a delayed one-time binding. // The resource still hasn't been found, so add a delayed one-time binding.
var provideTarget = context.GetService<IProvideValueTarget>(); var provideTarget = serviceProvider.GetService<IProvideValueTarget>();
if (provideTarget.TargetObject is IControl target && if (provideTarget.TargetObject is IControl target &&
provideTarget.TargetProperty is PropertyInfo property) provideTarget.TargetProperty is PropertyInfo property)

5
src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs

@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved. // Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Controls; using Avalonia.Controls;
using System.Collections.Generic; using System.Collections.Generic;
@ -37,6 +38,10 @@ namespace Avalonia.Markup.Xaml.Templates
public static IControl Load(object templateContent) public static IControl Load(object templateContent)
{ {
if (templateContent is Func<IServiceProvider, object> direct)
{
return (IControl)direct(null);
}
return ((TemplateContent)templateContent).Load(); return ((TemplateContent)templateContent).Load();
} }
} }

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/AvaloniaXamlIlRuntimeCompiler.cs

@ -28,7 +28,7 @@ namespace Avalonia.Markup.Xaml.XamlIl
var saveMethod = _asm.GetType().GetMethods() var saveMethod = _asm.GetType().GetMethods()
.FirstOrDefault(m => m.Name == "Save" && m.GetParameters().Length == 1); .FirstOrDefault(m => m.Name == "Save" && m.GetParameters().Length == 1);
if (saveMethod == null) if (saveMethod == null)
throw new PlatformNotSupportedException(); return;
try try
{ {
_builder.CreateGlobalFunctions(); _builder.CreateGlobalFunctions();

3
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -48,7 +48,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}, },
MarkupExtensionCustomResultTypes = MarkupExtensionCustomResultTypes =
{ {
bindingType bindingType,
typeSystem.GetType("Avalonia.UnsetValueType")
}, },
MarkupExtensionCustomResultHandler = MarkupExtensionCustomResultHandler =
runtimeHelpers.FindMethod(m => m.Name == "ApplyNonMatchingMarkupExtensionV1"), runtimeHelpers.FindMethod(m => m.Name == "ApplyNonMatchingMarkupExtensionV1"),

42
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs

@ -1,3 +1,4 @@
using System;
using XamlIl.Ast; using XamlIl.Ast;
using XamlIl.Transform; using XamlIl.Transform;
using XamlIl.TypeSystem; using XamlIl.TypeSystem;
@ -35,44 +36,39 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen) public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
{ {
var exts = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions");
var findNameScope = exts.FindMethod(m => m.Name == "FindNameScope");
var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register");
using (var nameLoc = context.GetLocal(context.Configuration.WellKnownTypes.String)) using (var nameLoc = context.GetLocal(context.Configuration.WellKnownTypes.String))
using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object)) using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object))
using (var nameScopeLoc = context.GetLocal(findNameScope.ReturnType))
{ {
var exts = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions");
var findNameScope = exts.FindMethod(m => m.Name == "FindNameScope");
var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register");
var exit = codeGen.DefineLabel(); var exit = codeGen.DefineLabel();
var call = codeGen.DefineLabel();
context.Emit(Value, codeGen, _property.PropertyType); // var target = {target}
codeGen.Stloc(targetLoc.Local);
codeGen // var name = {EmitName()}
// var name = {EmitName()} context.Emit(Value, codeGen, _property.PropertyType);
.Stloc(nameLoc.Local) codeGen.Stloc(nameLoc.Local)
// var target = {target} // target.Name = name
.Dup() .Ldloc(targetLoc.Local)
.Stloc(targetLoc.Local)
// {target}.Name = name
.Dup()
.Ldloc(nameLoc.Local) .Ldloc(nameLoc.Local)
.EmitCall(_property.Setter) .EmitCall(_property.Setter)
// var scope = {target}.FindNameScope() // var scope = target.FindNameScope()
.Ldloc(targetLoc.Local)
.EmitCall(findNameScope) .EmitCall(findNameScope)
.Stloc(nameScopeLoc.Local)
// if({scope} != null) goto call; // if({scope} != null) goto call;
.Dup() .Ldloc(nameScopeLoc.Local)
.Brtrue(call) .Brfalse(exit)
// goto: exit .Ldloc(nameScopeLoc.Local)
.Pop()
.Br(exit)
// call: {scope}.Register(name, target);
.MarkLabel(call)
.Ldloc(nameLoc.Local) .Ldloc(nameLoc.Local)
.Ldloc(targetLoc.Local) .Ldloc(targetLoc.Local)
.EmitCall(registerMethod) .EmitCall(registerMethod)
.MarkLabel(exit); .MarkLabel(exit);
} }
return XamlIlNodeEmitResult.Void; return XamlIlNodeEmitResult.Void(1);
} }
} }
} }

7
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/XNameTransformer.cs

@ -15,12 +15,15 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{ {
if (node is XamlIlAstObjectNode on) if (node is XamlIlAstObjectNode on)
{ {
foreach (var ch in on.Children) for (var c =0; c< on.Children.Count;c++)
{ {
var ch = on.Children[c];
if (ch is XamlIlAstXmlDirective d if (ch is XamlIlAstXmlDirective d
&& d.Namespace == XamlNamespaces.Xaml2006 && d.Namespace == XamlNamespaces.Xaml2006
&& d.Name == "Name") && d.Name == "Name")
return new XamlIlAstXamlPropertyValueNode(d,
on.Children[c] = new XamlIlAstXamlPropertyValueNode(d,
new XamlIlAstNamePropertyReference(d, on.Type, "Name", on.Type), new XamlIlAstNamePropertyReference(d, on.Type, "Name", on.Type),
d.Values); d.Values);
} }

7
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@ -62,6 +62,13 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
else else
throw new ArgumentException("Attempt to apply binding to non-avalonia property " + property); throw new ArgumentException("Attempt to apply binding to non-avalonia property " + property);
} }
else if (value is UnsetValueType unset)
{
if (property is AvaloniaProperty p)
((AvaloniaObject)target).SetValue(p, unset);
//TODO: Investigate
//throw new ArgumentException("Attempt to apply UnsetValue to non-avalonia property " + property);
}
else else
throw new ArgumentException("Don't know what to do with " + value.GetType()); throw new ArgumentException("Don't know what to do with " + value.GetType());
} }

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

@ -1 +1 @@
Subproject commit 89bc4d268d7ee48d0907cec24175a99759d0bc4a Subproject commit 4e7544ea2d152d22668b93c993d4965d5e9d515a

2
src/Markup/Avalonia.Markup/Data/MultiBinding.cs

@ -19,7 +19,7 @@ namespace Avalonia.Data
/// <summary> /// <summary>
/// Gets the collection of child bindings. /// Gets the collection of child bindings.
/// </summary> /// </summary>
[Content] [Content, AssignBinding]
public IList<IBinding> Bindings { get; set; } = new List<IBinding>(); public IList<IBinding> Bindings { get; set; } = new List<IBinding>();
/// <summary> /// <summary>

Loading…
Cancel
Save