diff --git a/samples/Generators.Sandbox/Controls/SignUpView.xaml b/samples/Generators.Sandbox/Controls/SignUpView.xaml
index c126f36f53..1cfb581cf9 100644
--- a/samples/Generators.Sandbox/Controls/SignUpView.xaml
+++ b/samples/Generators.Sandbox/Controls/SignUpView.xaml
@@ -8,7 +8,7 @@
Watermark="Please, enter user name..."
UseFloatingWatermark="True" />
ResolveNames(XamlDocument xaml);
+ ImmutableArray ResolveXmlNames(XamlDocument xaml);
+ ResolvedName ResolveName(IXamlType xamlType, string name, string? fieldModifier);
}
+internal record XamlXmlType(string Name, string? XmlNamespace, ImmutableArray GenericArguments);
+
+internal record ResolvedXmlName(XamlXmlType XmlType, string Name, string? FieldModifier);
internal record ResolvedName(string TypeName, string Name, string? FieldModifier);
diff --git a/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs b/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs
index 3688c35dfa..23c4f7fdda 100644
--- a/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs
+++ b/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs
@@ -5,27 +5,40 @@ namespace Avalonia.Generators.Common.Domain;
internal interface IViewResolver
{
- ResolvedView? ResolveView(string xaml);
+ ResolvedViewDocument? ResolveView(string xaml);
}
-internal record ResolvedViewInfo(string ClassName, string Namespace, bool IsWindow)
+internal record ResolvedViewInfo(string ClassName, string Namespace)
{
public string FullName => $"{Namespace}.{ClassName}";
public override string ToString() => FullName;
}
-internal record ResolvedView(string ClassName, string Namespace, bool IsWindow, XamlDocument Xaml)
- : ResolvedViewInfo(ClassName, Namespace, IsWindow);
+internal record ResolvedViewDocument(string ClassName, string Namespace, XamlDocument Xaml)
+ : ResolvedViewInfo(ClassName, Namespace);
-internal record ResolvedViewWithNames(
+internal record ResolvedXmlView(
+ string ClassName,
+ string Namespace,
+ ImmutableArray XmlNames)
+ : ResolvedViewInfo(ClassName, Namespace)
+{
+ public ResolvedXmlView(ResolvedViewInfo info, ImmutableArray xmlNames)
+ : this(info.ClassName, info.Namespace, xmlNames)
+ {
+
+ }
+}
+
+internal record ResolvedView(
string ClassName,
string Namespace,
bool IsWindow,
- ImmutableArray ResolvedNames)
- : ResolvedViewInfo(ClassName, Namespace, IsWindow)
+ ImmutableArray Names)
+ : ResolvedViewInfo(ClassName, Namespace)
{
- public ResolvedViewWithNames(ResolvedView view, ImmutableArray resolvedNames)
- : this(view.ClassName, view.Namespace, view.IsWindow, resolvedNames)
+ public ResolvedView(ResolvedViewInfo info, bool isWindow, ImmutableArray names)
+ : this(info.ClassName, info.Namespace, isWindow, names)
{
}
diff --git a/src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs b/src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs
index 11e926ac57..a6c111e99a 100644
--- a/src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs
+++ b/src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs
@@ -5,20 +5,31 @@ using System.Linq;
using Avalonia.Generators.Common.Domain;
using XamlX;
using XamlX.Ast;
+using XamlX.TypeSystem;
namespace Avalonia.Generators.Common;
internal class XamlXNameResolver
: INameResolver, IXamlAstVisitor
{
- private readonly List _items = new();
+ private readonly Dictionary _items = new();
- public ImmutableArray ResolveNames(XamlDocument xaml)
+ public ImmutableArray ResolveXmlNames(XamlDocument xaml)
{
_items.Clear();
xaml.Root.Visit(this);
xaml.Root.VisitChildren(this);
- return _items.ToImmutableArray();
+ return _items.Values.ToImmutableArray();
+ }
+
+ public ResolvedName ResolveName(IXamlType clrType, string name, string? fieldModifier)
+ {
+ var typeName = $"{clrType.Namespace}.{clrType.Name}";
+ var typeAgs = clrType.GenericArguments.Select(arg => arg.FullName).ToImmutableList();
+ var genericTypeName = typeAgs.Count == 0
+ ? $"global::{typeName}"
+ : $"global::{typeName}<{string.Join(", ", typeAgs.Select(arg => $"global::{arg}"))}>";
+ return new ResolvedName(genericTypeName, name, fieldModifier);
}
IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node)
@@ -26,9 +37,7 @@ internal class XamlXNameResolver
if (node is not XamlAstObjectNode objectNode)
return node;
- var clrType = objectNode.Type.GetClrType();
- if (!clrType.IsAvaloniaStyledElement())
- return node;
+ var xamlType = (XamlAstXmlTypeReference)objectNode.Type;
foreach (var child in objectNode.Children)
{
@@ -40,20 +49,17 @@ internal class XamlXNameResolver
propertyValueNode.Values[0] is XamlAstTextNode text)
{
var fieldModifier = TryGetFieldModifier(objectNode);
- var typeName = $"{clrType.Namespace}.{clrType.Name}";
- var typeAgs = clrType.GenericArguments.Select(arg => arg.FullName).ToImmutableList();
- var genericTypeName = typeAgs.Count == 0
- ? $"global::{typeName}"
- : $"global::{typeName}<{string.Join(", ", typeAgs.Select(arg => $"global::{arg}"))}>";
-
- var resolvedName = new ResolvedName(genericTypeName, text.Text, fieldModifier);
- if (_items.Contains(resolvedName))
+ var resolvedName = new ResolvedXmlName(ConvertType(xamlType), text.Text, fieldModifier);
+ if (_items.ContainsKey(text.Text))
continue;
- _items.Add(resolvedName);
+ _items.Add(text.Text, resolvedName);
}
}
return node;
+
+ static XamlXmlType ConvertType(XamlAstXmlTypeReference type) => new(type.Name, type.XmlNamespace,
+ type.GenericArguments.Select(ConvertType).ToImmutableArray());
}
void IXamlAstVisitor.Push(IXamlAstNode node) { }
diff --git a/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs b/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs
index 64432a2687..599fbdee36 100644
--- a/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs
+++ b/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs
@@ -10,16 +10,12 @@ using XamlX.TypeSystem;
namespace Avalonia.Generators.Common;
-internal class XamlXViewResolver(
- IXamlTypeSystem typeSystem,
- MiniCompiler compiler,
- bool checkTypeValidity = false,
- Action? onTypeInvalid = null) : IViewResolver, IXamlAstVisitor
+internal class XamlXViewResolver(MiniCompiler compiler) : IViewResolver, IXamlAstVisitor
{
- private ResolvedView? _resolvedClass;
+ private ResolvedViewDocument? _resolvedClass;
private XamlDocument? _xaml;
- public ResolvedView? ResolveView(string xaml)
+ public ResolvedViewDocument? ResolveView(string xaml)
{
_resolvedClass = null;
_xaml = XDocumentXamlParser.Parse(xaml, new Dictionary
@@ -32,32 +28,22 @@ internal class XamlXViewResolver(
_xaml.Root.VisitChildren(this);
return _resolvedClass;
}
-
+
IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node)
{
if (node is not XamlAstObjectNode objectNode)
return node;
- var clrType = objectNode.Type.GetClrType();
- if (!clrType.IsAvaloniaStyledElement())
- return node;
foreach (var child in objectNode.Children)
{
if (child is XamlAstXmlDirective { Name: "Class", Namespace: XamlNamespaces.Xaml2006 } directive
&& directive.Values[0] is XamlAstTextNode text)
{
- var existingType = typeSystem.FindType(text.Text);
- if (checkTypeValidity && existingType == null)
- {
- onTypeInvalid?.Invoke(text.Text);
- return node;
- }
-
var split = text.Text.Split('.');
var nameSpace = string.Join(".", split.Take(split.Length - 1));
var className = split.Last();
- _resolvedClass = new ResolvedView(className, nameSpace, existingType?.IsAvaloniaWindow() ?? false, _xaml!);
+ _resolvedClass = new ResolvedViewDocument(className, nameSpace, _xaml!);
return node;
}
}
diff --git a/src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs b/src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs
index 1be3e6e8a1..3e3bded3b3 100644
--- a/src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs
+++ b/src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs
@@ -1,6 +1,8 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using Avalonia.Generators.Common.Domain;
+using XamlX.Ast;
using XamlX.Compiler;
using XamlX.Emit;
using XamlX.Transform;
@@ -14,7 +16,22 @@ internal sealed class MiniCompiler : XamlCompiler