|
@@ -128,13 +128,13 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
break;
|
|
|
}
|
|
|
case SelectorGrammar.ChildSyntax child:
|
|
|
- result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Child);
|
|
|
+ result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.CombinatorSelectorType.Child);
|
|
|
break;
|
|
|
case SelectorGrammar.DescendantSyntax descendant:
|
|
|
- result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Descendant);
|
|
|
+ result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.CombinatorSelectorType.Descendant);
|
|
|
break;
|
|
|
case SelectorGrammar.TemplateSyntax template:
|
|
|
- result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.SelectorType.Template);
|
|
|
+ result = new XamlIlCombinatorSelector(result, XamlIlCombinatorSelector.CombinatorSelectorType.Template);
|
|
|
break;
|
|
|
case SelectorGrammar.NotSyntax not:
|
|
|
result = new XamlIlNotSelector(result, Create(not.Argument, typeResolver));
|
|
@@ -186,18 +186,50 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
=> TypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true));
|
|
|
pn.Values[0] = selector;
|
|
|
|
|
|
- return new AvaloniaXamlIlTargetTypeMetadataNode(on,
|
|
|
+ var templateType = GetLastTemplateTypeFromSelector(selector);
|
|
|
+
|
|
|
+ var styleNode = new AvaloniaXamlIlTargetTypeMetadataNode(on,
|
|
|
new XamlAstClrTypeReference(selector, selector.TargetType, false),
|
|
|
AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style);
|
|
|
+
|
|
|
+ return templateType switch
|
|
|
+ {
|
|
|
+ null => styleNode,
|
|
|
+ _ => new AvaloniaXamlIlTargetTypeMetadataNode(styleNode,
|
|
|
+ new XamlAstClrTypeReference(styleNode, templateType, false),
|
|
|
+ AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.ControlTemplate)
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ private static IXamlType GetLastTemplateTypeFromSelector(XamlIlSelectorNode node)
|
|
|
+ {
|
|
|
+ while (node is not null)
|
|
|
+ {
|
|
|
+ if (node is XamlIlCombinatorSelector
|
|
|
+ {
|
|
|
+ SelectorType: XamlIlCombinatorSelector.CombinatorSelectorType.Template
|
|
|
+ } templateSelector)
|
|
|
+ {
|
|
|
+ if (templateSelector.TargetType is {} targetType)
|
|
|
+ {
|
|
|
+ return targetType;
|
|
|
+ }
|
|
|
+ if (templateSelector.Previous is XamlIlNestingSelector nestingSelector)
|
|
|
+ {
|
|
|
+ return nestingSelector.TargetType;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ node = node.Previous;
|
|
|
+ }
|
|
|
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
abstract class XamlIlSelectorNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode<IXamlILEmitter, XamlILNodeEmitResult>
|
|
|
{
|
|
|
- protected XamlIlSelectorNode Previous { get; }
|
|
|
+ internal XamlIlSelectorNode Previous { get; }
|
|
|
public abstract IXamlType TargetType { get; }
|
|
|
|
|
|
public XamlIlSelectorNode(XamlIlSelectorNode previous,
|
|
@@ -289,19 +321,20 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
|
|
|
class XamlIlCombinatorSelector : XamlIlSelectorNode
|
|
|
{
|
|
|
- private readonly SelectorType _type;
|
|
|
+ private readonly CombinatorSelectorType _type;
|
|
|
|
|
|
- public enum SelectorType
|
|
|
+ public enum CombinatorSelectorType
|
|
|
{
|
|
|
Child,
|
|
|
Descendant,
|
|
|
Template
|
|
|
}
|
|
|
- public XamlIlCombinatorSelector(XamlIlSelectorNode previous, SelectorType type) : base(previous)
|
|
|
+ public XamlIlCombinatorSelector(XamlIlSelectorNode previous, CombinatorSelectorType type) : base(previous)
|
|
|
{
|
|
|
_type = type;
|
|
|
}
|
|
|
|
|
|
+ public CombinatorSelectorType SelectorType => _type;
|
|
|
public override IXamlType TargetType => null;
|
|
|
protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|