var br2 = Instruction.Create(OpCodes.Ldarg_0);
var ret = Instruction.Create(OpCodes.Ret);
il.Emit(OpCodes.Ldarg_0);
- var baseCtor = module.ImportReference(typeDef.BaseType.Resolve().GetConstructors().First(c => c.HasParameters == false));
- baseCtor = module.ImportReference(baseCtor.ResolveGenericParameters(typeDef.BaseType, module));
+ MethodReference baseCtor;
+ if (typeDef.BaseType.Resolve().GetConstructors().FirstOrDefault(c => c.HasParameters && c.Parameters.Count == 1 && c.Parameters[0].Name == "useCompiledXaml") is MethodDefinition baseCtorDef) {
+ baseCtor = module.ImportReference(baseCtorDef);
+ baseCtor = module.ImportReference(baseCtor.ResolveGenericParameters(typeDef.BaseType, module));
+ il.Emit(OpCodes.Ldarg_1);
+ }
+ else {
+ baseCtor = module.ImportReference(typeDef.BaseType.Resolve().GetConstructors().First(c => c.HasParameters == false));
+ baseCtor = module.ImportReference(baseCtor.ResolveGenericParameters(typeDef.BaseType, module));
+ }
il.Emit(OpCodes.Callvirt, baseCtor);
il.Emit(OpCodes.Nop);
{
class SetNamescopesAndRegisterNamesVisitor : IXamlNodeVisitor
{
- public SetNamescopesAndRegisterNamesVisitor(ILContext context)
- {
- Context = context;
- }
+ public SetNamescopesAndRegisterNamesVisitor(ILContext context) => Context = context;
ILContext Context { get; }
public bool IsResourceDictionary(ElementNode node)
{
- var parentVar = Context.Variables[(IElementNode)node];
+ var parentVar = Context.Variables[node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
public void Visit(RootNode node, INode parentNode)
{
- var namescopeVarDef = CreateNamescope();
+ var namescopeVarDef = GetOrCreateNameScope(node);
IList<string> namesInNamescope = new List<string>();
if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject"))))
SetNameScope(node, namescopeVarDef);
}
static bool IsDataTemplate(INode node, INode parentNode)
- {
- var parentElement = parentNode as IElementNode;
- INode createContent;
- if (parentElement != null && parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) &&
- createContent == node)
- return true;
- return false;
- }
+ => parentNode is IElementNode parentElement && parentElement.Properties.TryGetValue(XmlName._CreateContent, out INode createContent) && createContent == node;
- static bool IsStyle(INode node, INode parentNode)
- {
- var pnode = parentNode as ElementNode;
- return pnode != null && pnode.XmlType.Name == "Style";
- }
+ static bool IsStyle(INode node, INode parentNode) => parentNode is ElementNode pnode && pnode.XmlType.Name == "Style";
- static bool IsVisualStateGroupList(ElementNode node)
- {
- return node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode;
- }
+ static bool IsVisualStateGroupList(ElementNode node) => node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode;
static bool IsXNameProperty(ValueNode node, INode parentNode)
+ => parentNode is IElementNode parentElement && parentElement.Properties.TryGetValue(XmlName.xName, out INode xNameNode) && xNameNode == node;
+
+ VariableDefinition GetOrCreateNameScope(ElementNode node)
{
- var parentElement = parentNode as IElementNode;
- INode xNameNode;
- if (parentElement != null && parentElement.Properties.TryGetValue(XmlName.xName, out xNameNode) && xNameNode == node)
- return true;
- return false;
+ var module = Context.Body.Method.Module;
+ var vardef = new VariableDefinition(module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope")));
+ Context.Body.Variables.Add(vardef);
+ var stloc = Instruction.Create(OpCodes.Stloc, vardef);
+
+ if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Body.Method.Module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject")))) {
+ var namescoperef = ("Xamarin.Forms.Core", "Xamarin.Forms", "BindableObject");
+ Context.IL.Append(Context.Variables[node].LoadAs(module.GetTypeDefinition(namescoperef), module));
+ Context.IL.Emit(OpCodes.Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope"),
+ methodName: "GetNameScope",
+ parameterTypes: new[] { namescoperef },
+ isStatic: true));
+ Context.IL.Emit(OpCodes.Dup);
+ Context.IL.Emit(OpCodes.Brtrue, stloc);
+
+ Context.IL.Emit(OpCodes.Pop);
+ }
+ Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms.Internals", "NameScope"), parameterTypes: null));
+
+ Context.IL.Append(stloc);
+ return vardef;
}
VariableDefinition CreateNamescope()
_names[name] = scopedElement;
}
- public static INameScope GetNameScope(BindableObject bindable)
- {
- return (INameScope)bindable.GetValue(NameScopeProperty);
- }
+ public static INameScope GetNameScope(BindableObject bindable) => (INameScope)bindable.GetValue(NameScopeProperty);
public static void SetNameScope(BindableObject bindable, INameScope value)
{
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<local:Gh7097Base
+ xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:local="using:Xamarin.Forms.Xaml.UnitTests"
+ x:Class="Xamarin.Forms.Xaml.UnitTests.Gh7097"
+ Title="Foo"
+ x:Name="self">
+ <CollectionView ItemsSource="{Binding Items}" x:Name="collectionview">
+ <CollectionView.ItemsLayout>
+ <ListItemsLayout ItemSpacing="4">
+ <x:Arguments>
+ <ItemsLayoutOrientation>Vertical</ItemsLayoutOrientation>
+ </x:Arguments>
+ </ListItemsLayout>
+ </CollectionView.ItemsLayout>
+ <CollectionView.ItemTemplate>
+ <DataTemplate>
+ <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" BackgroundColor="Green">
+ <Button
+ Text="BTN 1"
+ HorizontalOptions="FillAndExpand"
+ CommandParameter="{Binding}"
+ Command="{Binding BindingContext.Button1Command, Source={x:Reference self}}"/>
+ <Button
+ Text="BTN 2"
+ HorizontalOptions="FillAndExpand"
+ CommandParameter="{Binding}"
+ Command="{Binding BindingContext.Button2Command, Source={x:Reference self}}"/>
+ </StackLayout>
+ </DataTemplate>
+ </CollectionView.ItemTemplate>
+ </CollectionView>
+</local:Gh7097Base>
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Windows.Input;
+using NUnit.Framework;
+using Xamarin.Forms;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public partial class Gh7097 : Gh7097Base
+ {
+ public Gh7097() => InitializeComponent();
+ public Gh7097(bool useCompiledXaml) : base(useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ class Tests
+ {
+ IReadOnlyList<string> _flags;
+ [SetUp]
+ public void Setup()
+ {
+ Device.PlatformServices = new MockPlatformServices();
+ _flags = Device.Flags;
+ Device.SetFlags(new List<string>(Device.Flags ?? new List<string>()) { "CollectionView_Experimental" }.AsReadOnly());
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ Device.PlatformServices = null;
+ Device.SetFlags(_flags);
+ }
+
+ [Test]
+ public void CanXReferenceRoot([Values(false, true)]bool useCompiledXaml)
+ {
+ var layout = new Gh7097(useCompiledXaml) { BindingContext = new {
+ Button1Command = new MockCommand(),
+ Button2Command = new MockCommand(),
+ } };
+ var cv = layout.Content as CollectionView;
+ var content = cv.ItemTemplate.CreateContent() as StackLayout;
+ var btn1 = content.Children[0] as Button;
+ Assert.That(btn1.Command, Is.TypeOf<MockCommand>());
+ }
+
+ [Test]
+ //this was later reported as https://github.com/xamarin/Xamarin.Forms/issues/7286
+ public void RegisteringXNameOnSubPages([Values(false, true)]bool useCompiledXaml)
+ {
+ var layout = new Gh7097(useCompiledXaml);
+ var s = layout.FindByName("self");
+ Assert.That(layout.self, Is.Not.Null);
+ Assert.That(layout.collectionview, Is.Not.Null);
+ }
+
+ class MockCommand : ICommand
+ {
+#pragma warning disable 0067
+ public event EventHandler CanExecuteChanged;
+#pragma warning restore 0067
+ public bool CanExecute(object parameter) => true;
+ public void Execute(object parameter) => throw new NotImplementedException();
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ContentPage
+ xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ x:Class="Xamarin.Forms.Xaml.UnitTests.Gh7097Base">
+ <ContentPage.ControlTemplate>
+ <ControlTemplate>
+ <StackLayout>
+ <Label Text="BASE" FontSize="30" FontAttributes="Bold" HorizontalOptions="CenterAndExpand" TextColor="Red"/>
+ <ContentPresenter HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
+ </StackLayout>
+ </ControlTemplate>
+ </ContentPage.ControlTemplate>
+</ContentPage>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+using Xamarin.Forms;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public partial class Gh7097Base : ContentPage
+ {
+ public Gh7097Base() => InitializeComponent();
+ public Gh7097Base(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+ }
+}
public List<XmlName> SkipProperties { get; set; }
- public Forms.Internals.INameScope Namescope {
- get {
- throw new NotImplementedException ();
- }
- }
+ public NameScopeRef NameScopeRef => throw new NotImplementedException();
public XmlType XmlType {
get;
Values[node] = value;
}
- if (value is BindableObject bindableValue && node.Namescope != (parentNode as IElementNode)?.Namescope)
- NameScope.SetNameScope(bindableValue, node.Namescope);
+ if (value is BindableObject bindableValue && node.NameScopeRef != (parentNode as IElementNode)?.NameScopeRef)
+ NameScope.SetNameScope(bindableValue, node.NameScopeRef.NameScope);
if (XamlLoader.ValueCreatedCallback != null) {
var name = node.XmlType.Name;
var rnode = (XamlLoader.RuntimeRootNode)node;
Values[node] = rnode.Root;
Context.Types[node] = rnode.Root.GetType();
- var bindableRoot = rnode.Root as BindableObject;
- if (bindableRoot != null)
- NameScope.SetNameScope(bindableRoot, node.Namescope);
+ if (rnode.Root is BindableObject bindable) {
+ if (NameScope.GetNameScope(bindable) is INameScope existingNs)
+ node.NameScopeRef.NameScope = existingNs;
+ else
+ NameScope.SetNameScope(bindable, node.NameScopeRef?.NameScope);
+ }
}
public void Visit(ListNode node, INode parentNode)
{
//this is a gross hack to keep ListNode alive. ListNode must go in favor of Properties
- XmlName name;
- if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out name))
+ if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out XmlName name))
node.XmlName = name;
}
ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof (ParameterAttribute))));
if (ctorInfo == null)
return true;
- foreach (var parameter in ctorInfo.GetParameters())
- {
+ foreach (var parameter in ctorInfo.GetParameters()) {
var propname =
parameter.CustomAttributes.First(ca => ca.AttributeType.FullName == "Xamarin.Forms.ParameterAttribute")
.ConstructorArguments.First()
.Value as string;
- if (!node.Properties.ContainsKey(new XmlName("", propname)))
- {
+ if (!node.Properties.ContainsKey(new XmlName("", propname))) {
missingArgName = propname;
return false;
}
{
object[] arguments = CreateArgumentsArray(node);
- if (!node.Properties.ContainsKey(XmlName.xFactoryMethod))
- {
+ if (!node.Properties.ContainsKey(XmlName.xFactoryMethod)) {
//non-default ctor
try {
return Activator.CreateInstance(nodeType, arguments);
var factoryMethod = ((string)((ValueNode)node.Properties[XmlName.xFactoryMethod]).Value);
Type[] types = arguments == null ? new Type[0] : arguments.Select(a => a.GetType()).ToArray();
- Func<MethodInfo, bool> isMatch = m => {
+
+ bool isMatch(MethodInfo m)
+ {
if (m.Name != factoryMethod)
return false;
var p = m.GetParameters();
if (!m.IsStatic)
return false;
for (var i = 0; i < p.Length; i++) {
- if ((p [i].ParameterType.IsAssignableFrom(types [i])))
+ if ((p[i].ParameterType.IsAssignableFrom(types[i])))
continue;
- var op_impl = p[i].ParameterType.GetImplicitConversionOperator(fromType: types[i], toType: p[i].ParameterType)
+ var op_impl = p[i].ParameterType.GetImplicitConversionOperator(fromType: types[i], toType: p[i].ParameterType)
?? types[i].GetImplicitConversionOperator(fromType: types[i], toType: p[i].ParameterType);
if (op_impl == null)
return false;
- arguments [i] = op_impl.Invoke(null, new [] { arguments [i]});
+ arguments[i] = op_impl.Invoke(null, new[] { arguments[i] });
}
return true;
- };
+ }
+
try {
var mi = nodeType.GetRuntimeMethods().FirstOrDefault(isMatch);
if (mi == null)
if (!enode.Properties.ContainsKey(XmlName.xArguments))
return null;
var node = enode.Properties[XmlName.xArguments];
- var elementNode = node as ElementNode;
- if (elementNode != null)
- {
+ if (node is ElementNode elementNode) {
var array = new object[1];
array[0] = Values[elementNode];
return array;
}
- var listnode = node as ListNode;
- if (listnode != null)
- {
+ if (node is ListNode listnode) {
var array = new object[listnode.CollectionItems.Count];
for (var i = 0; i < listnode.CollectionItems.Count; i++)
array[i] = Values[(ElementNode)listnode.CollectionItems[i]];
{
var n = ctorInfo.GetParameters().Length;
var array = new object[n];
- for (var i = 0; i < n; i++)
- {
+ for (var i = 0; i < n; i++) {
var parameter = ctorInfo.GetParameters()[i];
var propname =
parameter.CustomAttributes.First(attr => attr.AttributeType == typeof (ParameterAttribute))
.ConstructorArguments.First()
.Value as string;
var name = new XmlName("", propname);
- INode node;
- if (!enode.Properties.TryGetValue(name, out node))
- {
- throw new XamlParseException(
- String.Format("The Property {0} is required to create a {1} object.", propname, ctorInfo.DeclaringType.FullName),
- enode as IXmlLineInfo);
- }
+ if (!enode.Properties.TryGetValue(name, out INode node))
+ throw new XamlParseException($"The Property {propname} is required to create a {ctorInfo.DeclaringType.FullName} object.", enode as IXmlLineInfo);
if (!enode.SkipProperties.Contains(name))
enode.SkipProperties.Add(name);
var value = Context.Values[node];
return array;
}
- static bool IsXaml2009LanguagePrimitive(IElementNode node)
- {
- return node.NamespaceURI == XamlParser.X2009Uri;
- }
+ static bool IsXaml2009LanguagePrimitive(IElementNode node) => node.NamespaceURI == XamlParser.X2009Uri;
static object CreateLanguagePrimitive(Type nodeType, IElementNode node)
{
- object value = null;
+ object value;
if (nodeType == typeof (string))
value = String.Empty;
else if (nodeType == typeof (Uri))
else
value = Activator.CreateInstance(nodeType);
- if (node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode &&
- ((ValueNode)node.CollectionItems[0]).Value is string)
- {
- var valuestring = ((ValueNode)node.CollectionItems[0]).Value as string;
-
- if (nodeType == typeof(SByte)) {
- sbyte retval;
- if (sbyte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Int16)) {
- short retval;
- if (short.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Int32)) {
- int retval;
- if (int.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Int64)) {
- long retval;
- if (long.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Byte)) {
- byte retval;
- if (byte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(UInt16)) {
- ushort retval;
- if (ushort.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(UInt32)) {
- uint retval;
- if (uint.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(UInt64)) {
- ulong retval;
- if (ulong.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Single)) {
- float retval;
- if (float.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof(Double)) {
- double retval;
- if (double.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof (Boolean))
- {
- bool outbool;
- if (bool.TryParse(valuestring, out outbool))
- return outbool;
- }
- if (nodeType == typeof(TimeSpan)) {
- TimeSpan retval;
- if (TimeSpan.TryParse(valuestring, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
- if (nodeType == typeof (char))
- {
- char retval;
- if (char.TryParse(valuestring, out retval))
- return retval;
- }
+ if ( node.CollectionItems.Count == 1
+ && node.CollectionItems[0] is ValueNode
+ && ((ValueNode)node.CollectionItems[0]).Value is string valuestring) {
+ if (nodeType == typeof(SByte) && sbyte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var sbyteval))
+ return sbyteval;
+ if (nodeType == typeof(Int16) && short.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var int16val))
+ return int16val;
+ if (nodeType == typeof(Int32) && int.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var int32val))
+ return int32val;
+ if (nodeType == typeof(Int64) && long.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var int64val))
+ return int64val;
+ if (nodeType == typeof(Byte) && byte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var byteval))
+ return byteval;
+ if (nodeType == typeof(UInt16) && ushort.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var uint16val))
+ return uint16val;
+ if (nodeType == typeof(UInt32) && uint.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var uint32val))
+ return uint32val;
+ if (nodeType == typeof(UInt64) && ulong.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var uint64val))
+ return uint64val;
+ if (nodeType == typeof(Single) && float.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var singleval))
+ return singleval;
+ if (nodeType == typeof(Double) && double.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var doubleval))
+ return doubleval;
+ if (nodeType == typeof(Boolean) && bool.TryParse(valuestring, out var boolval))
+ return boolval;
+ if (nodeType == typeof(TimeSpan) && TimeSpan.TryParse(valuestring, CultureInfo.InvariantCulture, out TimeSpan timespanval))
+ return timespanval;
+ if (nodeType == typeof(char) && char.TryParse(valuestring, out var charval))
+ return charval;
if (nodeType == typeof (string))
return valuestring;
- if (nodeType == typeof (decimal))
- {
- decimal retval;
- if (decimal.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval))
- return retval;
- }
-
- else if (nodeType == typeof (Uri))
- {
- Uri retval;
- if (Uri.TryCreate(valuestring, UriKind.RelativeOrAbsolute, out retval))
- return retval;
- }
+ if (nodeType == typeof(decimal) && decimal.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out var decimalval))
+ return decimalval;
+ if (nodeType == typeof(Uri) && Uri.TryCreate(valuestring, UriKind.RelativeOrAbsolute, out Uri urival))
+ return urival;
}
return value;
}
}
-}
+}
\ No newline at end of file
{
class NamescopingVisitor : IXamlNodeVisitor
{
- readonly Dictionary<INode, INameScope> _scopes = new Dictionary<INode, INameScope>();
+ readonly Dictionary<INode, NameScopeRef> _scopes = new Dictionary<INode, NameScopeRef>();
public NamescopingVisitor(HydrationContext context)
- => Values = context.Values;
-
- Dictionary<INode, object> Values { get; set; }
+ {
+ }
public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
public bool StopOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => false;
- public void Visit(ValueNode node, INode parentNode)
- => _scopes[node] = _scopes[parentNode];
-
- public void Visit(MarkupNode node, INode parentNode)
- => _scopes[node] = _scopes[parentNode];
+ public void Visit(ValueNode node, INode parentNode) => _scopes[node] = _scopes[parentNode];
+ public void Visit(MarkupNode node, INode parentNode) => _scopes[node] = _scopes[parentNode];
public void Visit(ElementNode node, INode parentNode)
- => _scopes[node] = node.Namescope = (parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) || IsVisualStateGroupList(node))
- ? new NameScope()
+ => _scopes[node] = node.NameScopeRef = (parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) || IsVisualStateGroupList(node))
+ ? new NameScopeRef { NameScope = new NameScope() }
: _scopes[parentNode];
- public void Visit(RootNode node, INode parentNode)
- => _scopes[node] = node.Namescope = new NameScope();
+ public void Visit(RootNode node, INode parentNode) => _scopes[node] = node.NameScopeRef = new NameScopeRef { NameScope = new NameScope() };
public void Visit(ListNode node, INode parentNode) =>
_scopes[node] = _scopes[parentNode];
static bool IsDataTemplate(INode node, INode parentNode)
{
- var parentElement = parentNode as IElementNode;
- if ( parentElement != null
- && parentElement.Properties.TryGetValue(XmlName._CreateContent, out var createContent)
- && createContent == node)
+ if ( parentNode is IElementNode parentElement
+ && parentElement.Properties.TryGetValue(XmlName._CreateContent, out var createContent)
+ && createContent == node)
return true;
return false;
}
- static bool IsStyle(INode node, INode parentNode)
- => (parentNode as ElementNode)?.XmlType.Name == "Style";
-
- static bool IsVisualStateGroupList(ElementNode node)
- => node?.XmlType.Name == "VisualStateGroup" && node?.Parent is IListNode;
+ static bool IsStyle(INode node, INode parentNode) => (parentNode as ElementNode)?.XmlType.Name == "Style";
+ static bool IsVisualStateGroupList(ElementNode node) => node?.XmlType.Name == "VisualStateGroup" && node?.Parent is IListNode;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Xml;
using Xamarin.Forms.Internals;
-using Xamarin.Forms.Xaml.Internals;
namespace Xamarin.Forms.Xaml
{
return;
try {
- ((IElementNode)parentNode).Namescope.RegisterName((string)node.Value, Values[parentNode]);
+ ((IElementNode)parentNode).NameScopeRef.NameScope.RegisterName((string)node.Value, Values[parentNode]);
}
catch (ArgumentException ae) {
if (ae.ParamName != "name")
}
static bool IsXNameProperty(ValueNode node, INode parentNode)
- {
- var parentElement = parentNode as IElementNode;
- INode xNameNode;
- if (parentElement != null && parentElement.Properties.TryGetValue(XmlName.xName, out xNameNode) && xNameNode == node)
- return true;
- return false;
- }
+ => parentNode is IElementNode parentElement && parentElement.Properties.TryGetValue(XmlName.xName, out INode xNameNode) && xNameNode == node;
}
}
{
Dictionary<XmlName, INode> Properties { get; }
List<XmlName> SkipProperties { get; }
- INameScope Namescope { get; }
+ NameScopeRef NameScopeRef { get; }
XmlType XmlType { get; }
string NamespaceURI { get; }
}
List<INode> CollectionItems { get; }
}
+ class NameScopeRef
+ {
+ public INameScope NameScope { get; set; }
+ }
+
[DebuggerDisplay("{NamespaceUri}:{Name}")]
class XmlType
{
};
}
+
[DebuggerDisplay("{XmlType.Name}")]
class ElementNode : BaseNode, IValueNode, IElementNode
{
public List<INode> CollectionItems { get; }
public XmlType XmlType { get; }
public string NamespaceURI { get; }
- public INameScope Namescope { get; set; }
+ public NameScopeRef NameScopeRef { get; set; }
public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
{
bool IsDataTemplate(INode parentNode)
{
- var parentElement = parentNode as IElementNode;
- INode createContent;
- if (parentElement != null &&
- parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) &&
+ if (parentNode is IElementNode parentElement &&
+ parentElement.Properties.TryGetValue(XmlName._CreateContent, out INode createContent) &&
createContent == this)
return true;
return false;
set { services[typeof (IValueConverterProvider)] = value; }
}
- public object GetService(Type serviceType)
- {
- object service;
- return services.TryGetValue(serviceType, out service) ? service : null;
- }
+ public object GetService(Type serviceType) => services.TryGetValue(serviceType, out var service) ? service : null;
- public void Add(Type type, object service)
- {
- services.Add(type, service);
- }
+ public void Add(Type type, object service) => services.Add(type, service);
}
class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget
IEnumerable<object> IProvideParentValues.ParentObjects
{
- get
- {
+ get {
if (Node == null || Context == null)
yield break;
var n = Node;
- object obj = null;
var context = Context;
- while (n.Parent != null && context != null)
- {
- if (n.Parent is IElementNode)
- {
- if (context.Values.TryGetValue(n.Parent, out obj))
+ while (n.Parent != null && context != null) {
+ if (n.Parent is IElementNode) {
+ if (context.Values.TryGetValue(n.Parent, out var obj))
yield return obj;
- else
- {
+ else {
context = context.ParentContext;
continue;
}
this.scope = scope;
}
- IEnumerable<object> IProvideParentValues.ParentObjects
- => objectAndParents;
-
- object IProvideValueTarget.TargetObject
- => objectAndParents[0];
-
- object IProvideValueTarget.TargetProperty
- => targetProperty;
+ IEnumerable<object> IProvideParentValues.ParentObjects => objectAndParents;
+ object IProvideValueTarget.TargetObject => objectAndParents[0];
+ object IProvideValueTarget.TargetProperty => targetProperty;
public object FindByName(string name)
{
class ReferenceProvider : IReferenceProvider
{
readonly INode _node;
- internal ReferenceProvider(INode node)
- => _node = node;
+ internal ReferenceProvider(INode node) => _node = node;
public object FindByName(string name)
{
var n = _node;
- object value = null;
while (n != null) {
- if ((value = (n as IElementNode)?.Namescope?.FindByName(name)) != null)
+ object value;
+ if ((value = (n as IElementNode)?.NameScopeRef.NameScope?.FindByName(name)) != null)
return value;
n = n.Parent;
}
{
readonly Dictionary<string, string> namespaces = new Dictionary<string, string>();
- public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope)
- {
- throw new NotImplementedException();
- }
+ public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope) => throw new NotImplementedException();
public string LookupNamespace(string prefix)
{
- string result;
- if (namespaces.TryGetValue(prefix, out result))
+ if (namespaces.TryGetValue(prefix, out var result))
return result;
return null;
}
- public string LookupPrefix(string namespaceName)
- {
- throw new NotImplementedException();
- }
-
- public void Add(string prefix, string ns)
- {
- namespaces.Add(prefix, ns);
- }
+ public string LookupPrefix(string namespaceName) => throw new NotImplementedException();
+ public void Add(string prefix, string ns) => namespaces.Add(prefix, ns);
}
}
\ No newline at end of file