Browse Source

WIP2

xamlil-debug-info
Nikita Tsukanov 7 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. 7
      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 Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Markup.Xaml.XamlIl;
using Avalonia.Platform;
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 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");
themes.SelectionChanged += (sender, e) =>
{
@ -49,6 +64,7 @@ namespace ControlCatalog
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
AvaloniaXamlIlRuntimeCompiler.DumpRuntimeCompilationResults();
}
}
}

33
samples/ControlCatalog/MainWindow.xaml

@ -1,8 +1,39 @@
<Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
xmlns:pages="clr-namespace:ControlCatalog.Pages"
Title="Avalonia Control Gallery"
Icon="/Assets/test_icon.ico"
xmlns:local="clr-namespace:ControlCatalog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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>

21
src/Avalonia.Base/AvaloniaProperty.cs

@ -19,7 +19,7 @@ namespace Avalonia
/// <summary>
/// Represents an unset property value.
/// </summary>
public static readonly object UnsetValue = new Unset();
public static readonly object UnsetValue = new UnsetValueType();
private static int s_nextId;
private readonly Subject<AvaloniaPropertyChangedEventArgs> _initialized;
@ -546,16 +546,17 @@ namespace Avalonia
}
}
}
/// <summary>
/// Class representing the <see cref="UnsetValue"/>.
/// </summary>
public class UnsetValueType
{
/// <summary>
/// Class representing the <see cref="UnsetValue"/>.
/// Returns the string representation of the <see cref="UnsetValue"/>.
/// </summary>
private class Unset
{
/// <summary>
/// Returns the string representation of the <see cref="UnsetValue"/>.
/// </summary>
/// <returns>The string "(unset)".</returns>
public override string ToString() => "(unset)";
}
/// <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.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Avalonia.Markup.Xaml.XamlIl.Runtime;
using Portable.Xaml;
using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml
{
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)
@ -37,6 +39,18 @@ namespace Avalonia.Markup.Xaml
(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)
{
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)
{
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
// 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
// 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
// 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;
}
// 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
// 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;
}
}
// 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 &&
provideTarget.TargetProperty is PropertyInfo property)

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

@ -1,6 +1,7 @@
// 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.
using System;
using Avalonia.Controls;
using System.Collections.Generic;
@ -37,7 +38,11 @@ namespace Avalonia.Markup.Xaml.Templates
public static IControl Load(object templateContent)
{
if (templateContent is Func<IServiceProvider, object> direct)
{
return (IControl)direct(null);
}
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()
.FirstOrDefault(m => m.Name == "Save" && m.GetParameters().Length == 1);
if (saveMethod == null)
throw new PlatformNotSupportedException();
return;
try
{
_builder.CreateGlobalFunctions();

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

@ -48,7 +48,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
},
MarkupExtensionCustomResultTypes =
{
bindingType
bindingType,
typeSystem.GetType("Avalonia.UnsetValueType")
},
MarkupExtensionCustomResultHandler =
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.Transform;
using XamlIl.TypeSystem;
@ -35,44 +36,39 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
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 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 call = codeGen.DefineLabel();
// var target = {target}
codeGen.Stloc(targetLoc.Local);
// var name = {EmitName()}
context.Emit(Value, codeGen, _property.PropertyType);
codeGen
// var name = {EmitName()}
.Stloc(nameLoc.Local)
// var target = {target}
.Dup()
.Stloc(targetLoc.Local)
// {target}.Name = name
.Dup()
codeGen.Stloc(nameLoc.Local)
// target.Name = name
.Ldloc(targetLoc.Local)
.Ldloc(nameLoc.Local)
.EmitCall(_property.Setter)
// var scope = {target}.FindNameScope()
// var scope = target.FindNameScope()
.Ldloc(targetLoc.Local)
.EmitCall(findNameScope)
.Stloc(nameScopeLoc.Local)
// if({scope} != null) goto call;
.Dup()
.Brtrue(call)
// goto: exit
.Pop()
.Br(exit)
// call: {scope}.Register(name, target);
.MarkLabel(call)
.Ldloc(nameScopeLoc.Local)
.Brfalse(exit)
.Ldloc(nameScopeLoc.Local)
.Ldloc(nameLoc.Local)
.Ldloc(targetLoc.Local)
.EmitCall(registerMethod)
.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)
{
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
&& d.Namespace == XamlNamespaces.Xaml2006
&& d.Name == "Name")
return new XamlIlAstXamlPropertyValueNode(d,
on.Children[c] = new XamlIlAstXamlPropertyValueNode(d,
new XamlIlAstNamePropertyReference(d, on.Type, "Name", on.Type),
d.Values);
}

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

@ -62,6 +62,13 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
else
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
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>
/// Gets the collection of child bindings.
/// </summary>
[Content]
[Content, AssignBinding]
public IList<IBinding> Bindings { get; set; } = new List<IBinding>();
/// <summary>

Loading…
Cancel
Save