Browse Source

Merge pull request #11121 from AvaloniaUI/fix-grid-definitions

Fix GridDefinitions parsing with space separated syntax
pull/11131/head
Jumar Macato 3 years ago
committed by GitHub
parent
commit
bb637f525f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Avalonia.Base/Metadata/AvaloniaListAttribute.cs
  2. 2
      src/Avalonia.Controls/DefinitionList.cs
  3. 14
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs
  4. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  5. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github
  6. 31
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

23
src/Avalonia.Base/Metadata/AvaloniaListAttribute.cs

@ -0,0 +1,23 @@
using System;
namespace Avalonia.Metadata;
/// <summary>
/// Defines how compiler should split avalonia list string value before parsing individual items.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class AvaloniaListAttribute : Attribute
{
/// <summary>
/// Separator used to split input string.
/// Default value is ','.
/// </summary>
public string[]? Separators { get; init; }
/// <summary>
/// Split options used to split input string.
/// Default value is RemoveEmptyEntries with TrimEntries.
/// </summary>
// StringSplitOptions.TrimEntries = 2, but only on net6 target.
public StringSplitOptions SplitOptions { get; init; } = StringSplitOptions.RemoveEmptyEntries | (StringSplitOptions)2;
}

2
src/Avalonia.Controls/DefinitionList.cs

@ -1,9 +1,11 @@
using System.Collections;
using System.Collections.Specialized;
using Avalonia.Collections;
using Avalonia.Metadata;
namespace Avalonia.Controls
{
[AvaloniaList(Separators = new [] { ",", " " })]
public abstract class DefinitionList<T> : AvaloniaList<T> where T : DefinitionBase
{
public DefinitionList()

14
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs

@ -337,6 +337,20 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
var separators = new[] { "," };
var splitOptions = StringSplitOptions.RemoveEmptyEntries | trimOption;
var attribute = type.GetAllCustomAttributes().FirstOrDefault(a => a.Type == types.AvaloniaListAttribute);
if (attribute is not null)
{
if (attribute.Properties.TryGetValue("Separators", out var separatorsArray))
{
separators = ((Array)separatorsArray)?.OfType<string>().ToArray();
}
if (attribute.Properties.TryGetValue("SplitOptions", out var splitOptionsObj))
{
splitOptions = (StringSplitOptions)splitOptionsObj;
}
}
items = text.Split(separators, splitOptions ^ trimOption);
// Compiler targets netstandard, so we need to emulate StringSplitOptions.TrimEntries, if it was requested.
if (splitOptions.HasFlag(trimOption))

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -33,6 +33,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType InheritDataTypeFromItemsAttribute { get; }
public IXamlType MarkupExtensionOptionAttribute { get; }
public IXamlType MarkupExtensionDefaultOptionAttribute { get; }
public IXamlType AvaloniaListAttribute { get; }
public IXamlType AvaloniaList { get; }
public IXamlType OnExtensionType { get; }
public IXamlType UnsetValueType { get; }
@ -143,6 +144,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
InheritDataTypeFromItemsAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromItemsAttribute");
MarkupExtensionOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute");
MarkupExtensionDefaultOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute");
AvaloniaListAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute");
AvaloniaList = cfg.TypeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
OnExtensionType = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On");
AvaloniaObjectBindMethod = AvaloniaObjectExtensions.FindMethod("Bind", IDisposable, false, AvaloniaObject,

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

@ -1 +1 @@
Subproject commit 5d1025f30d0ed6d8f419d82959c148276301f393
Subproject commit e5254eb1b2017f78a92acd466c8fa1e47401056b

31
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs

@ -261,6 +261,37 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
var grid = AvaloniaRuntimeXamlLoader.Parse<Grid>(xaml);
Assert.Equal(4, grid.ColumnDefinitions.Count);
Assert.Equal(4, grid.RowDefinitions.Count);
var expected1 = new GridLength(100);
var expected2 = GridLength.Auto;
var expected3 = new GridLength(1, GridUnitType.Star);
var expected4 = new GridLength(100, GridUnitType.Star);
Assert.Equal(expected1, grid.ColumnDefinitions[0].Width);
Assert.Equal(expected2, grid.ColumnDefinitions[1].Width);
Assert.Equal(expected3, grid.ColumnDefinitions[2].Width);
Assert.Equal(expected4, grid.ColumnDefinitions[3].Width);
Assert.Equal(expected1, grid.RowDefinitions[0].Height);
Assert.Equal(expected2, grid.RowDefinitions[1].Height);
Assert.Equal(expected3, grid.RowDefinitions[2].Height);
Assert.Equal(expected4, grid.RowDefinitions[3].Height);
}
[Fact]
public void Grid_Row_Col_Definitions_Are_Parsed_Space_Delimiter()
{
var xaml = @"
<Grid xmlns='https://github.com/avaloniaui'
ColumnDefinitions='100 Auto * 100*'
RowDefinitions='100 Auto * 100*'>
</Grid>";
var grid = AvaloniaRuntimeXamlLoader.Parse<Grid>(xaml);
Assert.Equal(4, grid.ColumnDefinitions.Count);
Assert.Equal(4, grid.RowDefinitions.Count);

Loading…
Cancel
Save