diff --git a/src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs b/src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs index 41217005c5..b2c26017b9 100644 --- a/src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs +++ b/src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs @@ -1,6 +1,7 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; + namespace Avalonia.NameGenerator.Sandbox.Views { /// @@ -15,6 +16,7 @@ namespace Avalonia.NameGenerator.Sandbox.Views public SignUpView() { AvaloniaXamlLoader.Load(this); + UserNameTextBox.Text = "Joseph!"; UserNameValidation.Text = "User name is valid."; PasswordTextBox.Text = "qwerty"; diff --git a/src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj b/src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj index bc73022bc8..8ddbd84ccc 100644 --- a/src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj +++ b/src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj @@ -15,8 +15,9 @@ - - + + + diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/AttachedProps.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/AttachedProps.txt new file mode 100644 index 0000000000..9626d6ed5f --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/AttachedProps.txt @@ -0,0 +1,22 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/CustomControls.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/CustomControls.txt new file mode 100644 index 0000000000..f97368f68c --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/CustomControls.txt @@ -0,0 +1,26 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.ReactiveUI.RoutedViewHost ClrNamespaceRoutedViewHost {get; set;} + internal global::Avalonia.ReactiveUI.RoutedViewHost UriRoutedViewHost {get; set;} + internal global::Controls.CustomTextBox UserNameTextBox {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + ClrNamespaceRoutedViewHost = this.FindControl("ClrNamespaceRoutedViewHost"); + UriRoutedViewHost = this.FindControl("UriRoutedViewHost"); + UserNameTextBox = this.FindControl("UserNameTextBox"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/DataTemplates.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/DataTemplates.txt new file mode 100644 index 0000000000..9d1141bb64 --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/DataTemplates.txt @@ -0,0 +1,24 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + internal global::Avalonia.Controls.ListBox NamedListBox {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + NamedListBox = this.FindControl("NamedListBox"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/FieldModifier.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/FieldModifier.txt new file mode 100644 index 0000000000..e71dd6a5ed --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/FieldModifier.txt @@ -0,0 +1,32 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + public global::Avalonia.Controls.TextBox FirstNameTextBox {get; set;} + public global::Avalonia.Controls.TextBox LastNameTextBox {get; set;} + protected global::Avalonia.Controls.TextBox PasswordTextBox {get; set;} + private global::Avalonia.Controls.TextBox ConfirmPasswordTextBox {get; set;} + internal global::Avalonia.Controls.Button SignUpButton {get; set;} + internal global::Avalonia.Controls.Button RegisterButton {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + FirstNameTextBox = this.FindControl("FirstNameTextBox"); + LastNameTextBox = this.FindControl("LastNameTextBox"); + PasswordTextBox = this.FindControl("PasswordTextBox"); + ConfirmPasswordTextBox = this.FindControl("ConfirmPasswordTextBox"); + SignUpButton = this.FindControl("SignUpButton"); + RegisterButton = this.FindControl("RegisterButton"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/Code.cs b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/InitializeComponentCode.cs similarity index 83% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/Code.cs rename to src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/InitializeComponentCode.cs index 1f44606788..31283c80d8 100644 --- a/src/Avalonia.NameGenerator.Tests/GeneratedCode/Code.cs +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/InitializeComponentCode.cs @@ -2,9 +2,9 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -namespace Avalonia.NameGenerator.Tests.GeneratedCode +namespace Avalonia.NameGenerator.Tests.InitializeComponent.GeneratedCode { - public class Code + public static class InitializeComponentCode { public const string NamedControl = "NamedControl.txt"; public const string NamedControls = "NamedControls.txt"; @@ -22,7 +22,7 @@ namespace Avalonia.NameGenerator.Tests.GeneratedCode var assembly = typeof(XamlXNameResolverTests).Assembly; var fullResourceName = assembly .GetManifestResourceNames() - .First(name => name.EndsWith(generatedCodeResourceName)); + .First(name => name.Contains("InitializeComponent") && name.EndsWith(generatedCodeResourceName)); await using var stream = assembly.GetManifestResourceStream(fullResourceName); using var reader = new StreamReader(stream!); diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControl.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControl.txt new file mode 100644 index 0000000000..9626d6ed5f --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControl.txt @@ -0,0 +1,22 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControls.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControls.txt new file mode 100644 index 0000000000..7eda2d8811 --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControls.txt @@ -0,0 +1,26 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + internal global::Avalonia.Controls.TextBox PasswordTextBox {get; set;} + internal global::Avalonia.Controls.Button SignUpButton {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + PasswordTextBox = this.FindControl("PasswordTextBox"); + SignUpButton = this.FindControl("SignUpButton"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NoNamedControls.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NoNamedControls.txt new file mode 100644 index 0000000000..51c7369371 --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NoNamedControls.txt @@ -0,0 +1,22 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/SignUpView.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/SignUpView.txt new file mode 100644 index 0000000000..3a6473127b --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/SignUpView.txt @@ -0,0 +1,38 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Controls.CustomTextBox UserNameTextBox {get; set;} + internal global::Avalonia.Controls.TextBlock UserNameValidation {get; set;} + internal global::Avalonia.Controls.TextBox PasswordTextBox {get; set;} + internal global::Avalonia.Controls.TextBlock PasswordValidation {get; set;} + internal global::Avalonia.Controls.ListBox AwesomeListView {get; set;} + internal global::Avalonia.Controls.TextBox ConfirmPasswordTextBox {get; set;} + internal global::Avalonia.Controls.TextBlock ConfirmPasswordValidation {get; set;} + internal global::Avalonia.Controls.Button SignUpButton {get; set;} + internal global::Avalonia.Controls.TextBlock CompoundValidation {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + UserNameValidation = this.FindControl("UserNameValidation"); + PasswordTextBox = this.FindControl("PasswordTextBox"); + PasswordValidation = this.FindControl("PasswordValidation"); + AwesomeListView = this.FindControl("AwesomeListView"); + ConfirmPasswordTextBox = this.FindControl("ConfirmPasswordTextBox"); + ConfirmPasswordValidation = this.FindControl("ConfirmPasswordValidation"); + SignUpButton = this.FindControl("SignUpButton"); + CompoundValidation = this.FindControl("CompoundValidation"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControl.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControl.txt new file mode 100644 index 0000000000..9626d6ed5f --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControl.txt @@ -0,0 +1,22 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControls.txt b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControls.txt new file mode 100644 index 0000000000..7eda2d8811 --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControls.txt @@ -0,0 +1,26 @@ +// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Sample.App +{ + partial class SampleView + { + internal global::Avalonia.Controls.TextBox UserNameTextBox {get; set;} + internal global::Avalonia.Controls.TextBox PasswordTextBox {get; set;} + internal global::Avalonia.Controls.Button SignUpButton {get; set;} + + public void InitializeComponent(bool loadXaml = true) + { + if (loadXaml) + { + AvaloniaXamlLoader.Load(this); + } + + UserNameTextBox = this.FindControl("UserNameTextBox"); + PasswordTextBox = this.FindControl("PasswordTextBox"); + SignUpButton = this.FindControl("SignUpButton"); + } + } +} diff --git a/src/Avalonia.NameGenerator.Tests/InitializeComponent/InitializeComponentCodeGeneratorTests.cs b/src/Avalonia.NameGenerator.Tests/InitializeComponent/InitializeComponentCodeGeneratorTests.cs new file mode 100644 index 0000000000..85a5bc5d07 --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/InitializeComponent/InitializeComponentCodeGeneratorTests.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; +using Avalonia.NameGenerator.Compiler; +using Avalonia.NameGenerator.Generator; +using Avalonia.NameGenerator.Tests.InitializeComponent.GeneratedCode; +using Avalonia.NameGenerator.Tests.OnlyProperties.GeneratedCode; +using Avalonia.NameGenerator.Tests.Views; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Avalonia.NameGenerator.Tests.InitializeComponent +{ + public class InitializeComponentCodeGeneratorTests + { + [Theory] + [InlineData(InitializeComponentCode.NamedControl, View.NamedControl)] + [InlineData(InitializeComponentCode.NamedControls, View.NamedControls)] + [InlineData(InitializeComponentCode.XNamedControl, View.XNamedControl)] + [InlineData(InitializeComponentCode.XNamedControls, View.XNamedControls)] + [InlineData(InitializeComponentCode.NoNamedControls, View.NoNamedControls)] + [InlineData(InitializeComponentCode.CustomControls, View.CustomControls)] + [InlineData(InitializeComponentCode.DataTemplates, View.DataTemplates)] + [InlineData(InitializeComponentCode.SignUpView, View.SignUpView)] + [InlineData(InitializeComponentCode.AttachedProps, View.AttachedProps)] + [InlineData(InitializeComponentCode.FieldModifier, View.FieldModifier)] + public async Task Should_Generate_FindControl_Refs_From_Avalonia_Markup_File(string expectation, string markup) + { + var compilation = + View.CreateAvaloniaCompilation() + .WithCustomTextBox(); + + var classResolver = new XamlXViewResolver( + new RoslynTypeSystem(compilation), + MiniCompiler.CreateDefault( + new RoslynTypeSystem(compilation), + MiniCompiler.AvaloniaXmlnsDefinitionAttribute)); + + var xaml = await View.Load(markup); + var classInfo = classResolver.ResolveView(xaml); + var nameResolver = new XamlXNameResolver(); + var names = nameResolver.ResolveNames(classInfo.Xaml); + + var generator = new InitializeComponentCodeGenerator(); + var code = generator + .GenerateCode("SampleView", "Sample.App", names) + .Replace("\r", string.Empty); + + var expected = await InitializeComponentCode.Load(expectation); + CSharpSyntaxTree.ParseText(code); + Assert.Equal(expected.Replace("\r", string.Empty), code); + } + } +} \ No newline at end of file diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/AttachedProps.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/AttachedProps.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/AttachedProps.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/AttachedProps.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/CustomControls.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/CustomControls.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/CustomControls.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/CustomControls.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/DataTemplates.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/DataTemplates.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/DataTemplates.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/DataTemplates.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/FieldModifier.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/FieldModifier.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/FieldModifier.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/FieldModifier.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControl.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControl.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControl.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControl.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControls.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControls.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControls.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControls.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/NoNamedControls.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NoNamedControls.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/NoNamedControls.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NoNamedControls.txt diff --git a/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/OnlyPropertiesCode.cs b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/OnlyPropertiesCode.cs new file mode 100644 index 0000000000..4cba8cdfce --- /dev/null +++ b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/OnlyPropertiesCode.cs @@ -0,0 +1,33 @@ +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Avalonia.NameGenerator.Tests.OnlyProperties.GeneratedCode +{ + public static class OnlyPropertiesCode + { + public const string NamedControl = "NamedControl.txt"; + public const string NamedControls = "NamedControls.txt"; + public const string XNamedControl = "xNamedControl.txt"; + public const string XNamedControls = "xNamedControls.txt"; + public const string NoNamedControls = "NoNamedControls.txt"; + public const string CustomControls = "CustomControls.txt"; + public const string DataTemplates = "DataTemplates.txt"; + public const string SignUpView = "SignUpView.txt"; + public const string AttachedProps = "AttachedProps.txt"; + public const string FieldModifier = "FieldModifier.txt"; + + public static async Task Load(string generatedCodeResourceName) + { + var assembly = typeof(XamlXNameResolverTests).Assembly; + var fullResourceName = assembly + .GetManifestResourceNames() + .First(name => name.Contains("OnlyProperties") && name.EndsWith(generatedCodeResourceName)); + + await using var stream = assembly.GetManifestResourceStream(fullResourceName); + using var reader = new StreamReader(stream!); + return await reader.ReadToEndAsync(); + } + } +} \ No newline at end of file diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/SignUpView.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/SignUpView.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/SignUpView.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/SignUpView.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControl.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControl.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControl.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControl.txt diff --git a/src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControls.txt b/src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControls.txt similarity index 100% rename from src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControls.txt rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControls.txt diff --git a/src/Avalonia.NameGenerator.Tests/FindControlNameGeneratorTests.cs b/src/Avalonia.NameGenerator.Tests/OnlyProperties/OnlyPropertiesCodeGeneratorTests.cs similarity index 56% rename from src/Avalonia.NameGenerator.Tests/FindControlNameGeneratorTests.cs rename to src/Avalonia.NameGenerator.Tests/OnlyProperties/OnlyPropertiesCodeGeneratorTests.cs index d4d714ccb1..556cdab903 100644 --- a/src/Avalonia.NameGenerator.Tests/FindControlNameGeneratorTests.cs +++ b/src/Avalonia.NameGenerator.Tests/OnlyProperties/OnlyPropertiesCodeGeneratorTests.cs @@ -1,26 +1,26 @@ using System.Threading.Tasks; using Avalonia.NameGenerator.Compiler; using Avalonia.NameGenerator.Generator; -using Avalonia.NameGenerator.Tests.GeneratedCode; +using Avalonia.NameGenerator.Tests.OnlyProperties.GeneratedCode; using Avalonia.NameGenerator.Tests.Views; using Microsoft.CodeAnalysis.CSharp; using Xunit; -namespace Avalonia.NameGenerator.Tests +namespace Avalonia.NameGenerator.Tests.OnlyProperties { public class FindControlNameGeneratorTests { [Theory] - [InlineData(Code.NamedControl, View.NamedControl)] - [InlineData(Code.NamedControls, View.NamedControls)] - [InlineData(Code.XNamedControl, View.XNamedControl)] - [InlineData(Code.XNamedControls, View.XNamedControls)] - [InlineData(Code.NoNamedControls, View.NoNamedControls)] - [InlineData(Code.CustomControls, View.CustomControls)] - [InlineData(Code.DataTemplates, View.DataTemplates)] - [InlineData(Code.SignUpView, View.SignUpView)] - [InlineData(Code.AttachedProps, View.AttachedProps)] - [InlineData(Code.FieldModifier, View.FieldModifier)] + [InlineData(OnlyPropertiesCode.NamedControl, View.NamedControl)] + [InlineData(OnlyPropertiesCode.NamedControls, View.NamedControls)] + [InlineData(OnlyPropertiesCode.XNamedControl, View.XNamedControl)] + [InlineData(OnlyPropertiesCode.XNamedControls, View.XNamedControls)] + [InlineData(OnlyPropertiesCode.NoNamedControls, View.NoNamedControls)] + [InlineData(OnlyPropertiesCode.CustomControls, View.CustomControls)] + [InlineData(OnlyPropertiesCode.DataTemplates, View.DataTemplates)] + [InlineData(OnlyPropertiesCode.SignUpView, View.SignUpView)] + [InlineData(OnlyPropertiesCode.AttachedProps, View.AttachedProps)] + [InlineData(OnlyPropertiesCode.FieldModifier, View.FieldModifier)] public async Task Should_Generate_FindControl_Refs_From_Avalonia_Markup_File(string expectation, string markup) { var compilation = @@ -38,12 +38,12 @@ namespace Avalonia.NameGenerator.Tests var nameResolver = new XamlXNameResolver(); var names = nameResolver.ResolveNames(classInfo.Xaml); - var generator = new FindControlCodeGenerator(); + var generator = new OnlyPropertiesCodeGenerator(); var code = generator .GenerateCode("SampleView", "Sample.App", names) .Replace("\r", string.Empty); - var expected = await Code.Load(expectation); + var expected = await OnlyPropertiesCode.Load(expectation); CSharpSyntaxTree.ParseText(code); Assert.Equal(expected.Replace("\r", string.Empty), code); } diff --git a/src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs b/src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs index adbc54985e..67a6eba284 100644 --- a/src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs +++ b/src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Runtime.CompilerServices; using Avalonia.NameGenerator.Compiler; using Avalonia.NameGenerator.Domain; @@ -10,9 +11,21 @@ using Microsoft.CodeAnalysis.CSharp; namespace Avalonia.NameGenerator { + public enum BuildProperties + { + AvaloniaNameGeneratorBehavior = 0 + } + + public enum Behaviors + { + OnlyProperties = 0, + InitializeComponent, + } + [Generator] public class AvaloniaNameSourceGenerator : ISourceGenerator { + public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) @@ -20,12 +33,26 @@ namespace Avalonia.NameGenerator var compilation = (CSharpCompilation)context.Compilation; var types = new RoslynTypeSystem(compilation); var compiler = MiniCompiler.CreateDefault(types, MiniCompiler.AvaloniaXmlnsDefinitionAttribute); - + + var behaviorName = context.GetMSBuildProperty(nameof(BuildProperties.AvaloniaNameGeneratorBehavior), ""); + + if(!Behaviors.TryParse(behaviorName, out Behaviors behavior)) + { + behavior = Behaviors.OnlyProperties; + } + + ICodeGenerator generator = behavior switch { + Behaviors.OnlyProperties => new OnlyPropertiesCodeGenerator(), + Behaviors.InitializeComponent => new InitializeComponentCodeGenerator(), + _ => throw new ArgumentOutOfRangeException() + }; + + INameGenerator avaloniaNameGenerator = new AvaloniaNameGenerator( new XamlXViewResolver(types, compiler, true, type => ReportInvalidType(context, type)), new XamlXNameResolver(), - new FindControlCodeGenerator()); + generator); try { diff --git a/src/Avalonia.NameGenerator/Generator.props b/src/Avalonia.NameGenerator/Generator.props index a0f3171ddb..0d5cf5fb85 100644 --- a/src/Avalonia.NameGenerator/Generator.props +++ b/src/Avalonia.NameGenerator/Generator.props @@ -1,11 +1,14 @@  + - + + OnlyProperties + - \ No newline at end of file + diff --git a/src/Avalonia.NameGenerator/Generator/InitializeComponentCodeGenerator.cs b/src/Avalonia.NameGenerator/Generator/InitializeComponentCodeGenerator.cs new file mode 100644 index 0000000000..247774a651 --- /dev/null +++ b/src/Avalonia.NameGenerator/Generator/InitializeComponentCodeGenerator.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using System.Linq; +using Avalonia.NameGenerator.Domain; + +namespace Avalonia.NameGenerator.Generator +{ + internal class InitializeComponentCodeGenerator: ICodeGenerator + { + public string GenerateCode(string className, string nameSpace, IEnumerable names) + { + var properties = new List(); + var initializations = new List(); + foreach (var info in names) + { + properties.Add($" {info.FieldModifier} global::{info.TypeName} {info.Name} {{get; set;}}"); + initializations.Add($" {info.Name} = this.FindControl(\"{info.Name}\");"); + } + + return $@"// + +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace {nameSpace} +{{ + partial class {className} + {{ +{string.Join("\n", properties)} + + public void InitializeComponent(bool loadXaml = true) + {{ + if (loadXaml) + {{ + AvaloniaXamlLoader.Load(this); + }} + +{string.Join("\n", initializations)} + }} + }} +}} +"; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.NameGenerator/Generator/FindControlCodeGenerator.cs b/src/Avalonia.NameGenerator/Generator/OnlyPropertiesCodeGenerator.cs similarity index 92% rename from src/Avalonia.NameGenerator/Generator/FindControlCodeGenerator.cs rename to src/Avalonia.NameGenerator/Generator/OnlyPropertiesCodeGenerator.cs index a6dd275d61..b3d4b0064d 100644 --- a/src/Avalonia.NameGenerator/Generator/FindControlCodeGenerator.cs +++ b/src/Avalonia.NameGenerator/Generator/OnlyPropertiesCodeGenerator.cs @@ -4,7 +4,7 @@ using Avalonia.NameGenerator.Domain; namespace Avalonia.NameGenerator.Generator { - internal class FindControlCodeGenerator : ICodeGenerator + internal class OnlyPropertiesCodeGenerator : ICodeGenerator { public string GenerateCode(string className, string nameSpace, IEnumerable names) { diff --git a/src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs b/src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs index 5f72aed48a..a110432a78 100644 --- a/src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs +++ b/src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs @@ -82,4 +82,4 @@ namespace Avalonia.NameGenerator.Generator }; } } -} \ No newline at end of file +} diff --git a/version.json b/version.json index 9d636ccb2a..3fb9f3880b 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.2.1-preview", + "version": "0.3.1-preview", "assemblyVersion": { "precision": "revision" },