Browse Source

feature: Add InitializeComponent Source Generator Behavior (#29)

* Closes https://github.com/AvaloniaUI/Avalonia.NameGenerator/issues/28
pull/10407/head
GMIKE 5 years ago
committed by GitHub
parent
commit
398fc792b3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs
  2. 5
      src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj
  3. 22
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/AttachedProps.txt
  4. 26
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/CustomControls.txt
  5. 24
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/DataTemplates.txt
  6. 32
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/FieldModifier.txt
  7. 6
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/InitializeComponentCode.cs
  8. 22
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControl.txt
  9. 26
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControls.txt
  10. 22
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NoNamedControls.txt
  11. 38
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/SignUpView.txt
  12. 22
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControl.txt
  13. 26
      src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControls.txt
  14. 52
      src/Avalonia.NameGenerator.Tests/InitializeComponent/InitializeComponentCodeGeneratorTests.cs
  15. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/AttachedProps.txt
  16. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/CustomControls.txt
  17. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/DataTemplates.txt
  18. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/FieldModifier.txt
  19. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControl.txt
  20. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControls.txt
  21. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NoNamedControls.txt
  22. 33
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/OnlyPropertiesCode.cs
  23. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/SignUpView.txt
  24. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControl.txt
  25. 0
      src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControls.txt
  26. 28
      src/Avalonia.NameGenerator.Tests/OnlyProperties/OnlyPropertiesCodeGeneratorTests.cs
  27. 31
      src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs
  28. 7
      src/Avalonia.NameGenerator/Generator.props
  29. 44
      src/Avalonia.NameGenerator/Generator/InitializeComponentCodeGenerator.cs
  30. 2
      src/Avalonia.NameGenerator/Generator/OnlyPropertiesCodeGenerator.cs
  31. 2
      src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs
  32. 2
      version.json

2
src/Avalonia.NameGenerator.Sandbox/Views/SignUpView.xaml.cs

@ -1,6 +1,7 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Avalonia.NameGenerator.Sandbox.Views
{
/// <summary>
@ -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";

5
src/Avalonia.NameGenerator.Tests/Avalonia.NameGenerator.Tests.csproj

@ -15,8 +15,9 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Views/*.xml" />
<EmbeddedResource Include="GeneratedCode/*.txt" />
<EmbeddedResource Include="Views\*.xml" />
<EmbeddedResource Include="OnlyProperties\GeneratedCode\*.txt" />
<EmbeddedResource Include="InitializeComponent\GeneratedCode\*.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Avalonia.NameGenerator\Avalonia.NameGenerator.csproj" />

22
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/AttachedProps.txt

@ -0,0 +1,22 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
}
}
}

26
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/CustomControls.txt

@ -0,0 +1,26 @@
// <auto-generated />
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<global::Avalonia.ReactiveUI.RoutedViewHost>("ClrNamespaceRoutedViewHost");
UriRoutedViewHost = this.FindControl<global::Avalonia.ReactiveUI.RoutedViewHost>("UriRoutedViewHost");
UserNameTextBox = this.FindControl<global::Controls.CustomTextBox>("UserNameTextBox");
}
}
}

24
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/DataTemplates.txt

@ -0,0 +1,24 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
NamedListBox = this.FindControl<global::Avalonia.Controls.ListBox>("NamedListBox");
}
}
}

32
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/FieldModifier.txt

@ -0,0 +1,32 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("FirstNameTextBox");
LastNameTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("LastNameTextBox");
PasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("PasswordTextBox");
ConfirmPasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("ConfirmPasswordTextBox");
SignUpButton = this.FindControl<global::Avalonia.Controls.Button>("SignUpButton");
RegisterButton = this.FindControl<global::Avalonia.Controls.Button>("RegisterButton");
}
}
}

6
src/Avalonia.NameGenerator.Tests/GeneratedCode/Code.cs → 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!);

22
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControl.txt

@ -0,0 +1,22 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
}
}
}

26
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NamedControls.txt

@ -0,0 +1,26 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
PasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("PasswordTextBox");
SignUpButton = this.FindControl<global::Avalonia.Controls.Button>("SignUpButton");
}
}
}

22
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/NoNamedControls.txt

@ -0,0 +1,22 @@
// <auto-generated />
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Sample.App
{
partial class SampleView
{
public void InitializeComponent(bool loadXaml = true)
{
if (loadXaml)
{
AvaloniaXamlLoader.Load(this);
}
}
}
}

38
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/SignUpView.txt

@ -0,0 +1,38 @@
// <auto-generated />
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<global::Controls.CustomTextBox>("UserNameTextBox");
UserNameValidation = this.FindControl<global::Avalonia.Controls.TextBlock>("UserNameValidation");
PasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("PasswordTextBox");
PasswordValidation = this.FindControl<global::Avalonia.Controls.TextBlock>("PasswordValidation");
AwesomeListView = this.FindControl<global::Avalonia.Controls.ListBox>("AwesomeListView");
ConfirmPasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("ConfirmPasswordTextBox");
ConfirmPasswordValidation = this.FindControl<global::Avalonia.Controls.TextBlock>("ConfirmPasswordValidation");
SignUpButton = this.FindControl<global::Avalonia.Controls.Button>("SignUpButton");
CompoundValidation = this.FindControl<global::Avalonia.Controls.TextBlock>("CompoundValidation");
}
}
}

22
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControl.txt

@ -0,0 +1,22 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
}
}
}

26
src/Avalonia.NameGenerator.Tests/InitializeComponent/GeneratedCode/xNamedControls.txt

@ -0,0 +1,26 @@
// <auto-generated />
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<global::Avalonia.Controls.TextBox>("UserNameTextBox");
PasswordTextBox = this.FindControl<global::Avalonia.Controls.TextBox>("PasswordTextBox");
SignUpButton = this.FindControl<global::Avalonia.Controls.Button>("SignUpButton");
}
}
}

52
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);
}
}
}

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/AttachedProps.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/AttachedProps.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/CustomControls.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/CustomControls.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/DataTemplates.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/DataTemplates.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/FieldModifier.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/FieldModifier.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControl.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControl.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/NamedControls.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NamedControls.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/NoNamedControls.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/NoNamedControls.txt

33
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<string> 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();
}
}
}

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/SignUpView.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/SignUpView.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControl.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControl.txt

0
src/Avalonia.NameGenerator.Tests/GeneratedCode/xNamedControls.txt → src/Avalonia.NameGenerator.Tests/OnlyProperties/GeneratedCode/xNamedControls.txt

28
src/Avalonia.NameGenerator.Tests/FindControlNameGeneratorTests.cs → 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);
}

31
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
{

7
src/Avalonia.NameGenerator/Generator.props

@ -1,11 +1,14 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="SourceItemGroup"/>
<CompilerVisibleProperty Include="AvaloniaNameGeneratorBehavior" />
</ItemGroup>
<PropertyGroup>
<AvaloniaNameGeneratorBehavior Condition="'$(AvaloniaNameGeneratorBehavior)' == ''">OnlyProperties</AvaloniaNameGeneratorBehavior>
</PropertyGroup>
<Target Name="_InjectAdditionalFiles" BeforeTargets="GenerateMSBuildEditorConfigFileShouldRun">
<ItemGroup>
<AdditionalFiles Include="@(AvaloniaXaml)" SourceItemGroup="AvaloniaXaml" />
</ItemGroup>
</Target>
</Project>
</Project>

44
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<ResolvedName> names)
{
var properties = new List<string>();
var initializations = new List<string>();
foreach (var info in names)
{
properties.Add($" {info.FieldModifier} global::{info.TypeName} {info.Name} {{get; set;}}");
initializations.Add($" {info.Name} = this.FindControl<global::{info.TypeName}>(\"{info.Name}\");");
}
return $@"// <auto-generated />
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)}
}}
}}
}}
";
}
}
}

2
src/Avalonia.NameGenerator/Generator/FindControlCodeGenerator.cs → 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<ResolvedName> names)
{

2
src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs

@ -82,4 +82,4 @@ namespace Avalonia.NameGenerator.Generator
};
}
}
}
}

2
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"
},

Loading…
Cancel
Save