Browse Source

feature: Ability to specify default field modifier, closes #31

pull/10407/head
artyom 6 years ago
parent
commit
b5ddad6ec3
  1. 48
      src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs
  2. 2
      src/Avalonia.NameGenerator/Generator.props
  3. 10
      src/Avalonia.NameGenerator/Generator/XamlXNameResolver.cs
  4. 28
      src/Avalonia.NameGenerator/GeneratorOptions.cs

48
src/Avalonia.NameGenerator/AvaloniaNameSourceGenerator.cs

@ -17,26 +17,10 @@ namespace Avalonia.NameGenerator
public void Execute(GeneratorExecutionContext context) public void Execute(GeneratorExecutionContext context)
{ {
var compilation = (CSharpCompilation)context.Compilation; var generator = CreateNameGenerator(context);
var types = new RoslynTypeSystem(compilation);
var compiler = MiniCompiler.CreateDefault(types, MiniCompiler.AvaloniaXmlnsDefinitionAttribute);
var options = new GeneratorOptions(context);
ICodeGenerator generator = options.AvaloniaNameGeneratorBehavior switch {
Behavior.OnlyProperties => new OnlyPropertiesCodeGenerator(),
Behavior.InitializeComponent => new InitializeComponentCodeGenerator(),
_ => throw new ArgumentOutOfRangeException()
};
INameGenerator avaloniaNameGenerator =
new AvaloniaNameGenerator(
new XamlXViewResolver(types, compiler, true, type => ReportInvalidType(context, type)),
new XamlXNameResolver(),
generator);
try try
{ {
var partials = avaloniaNameGenerator.GenerateNameReferences(context.AdditionalFiles); var partials = generator.GenerateNameReferences(context.AdditionalFiles);
foreach (var partial in partials) context.AddSource(partial.FileName, partial.Content); foreach (var partial in partials) context.AddSource(partial.FileName, partial.Content);
} }
catch (Exception exception) catch (Exception exception)
@ -45,10 +29,29 @@ namespace Avalonia.NameGenerator
} }
} }
private static INameGenerator CreateNameGenerator(GeneratorExecutionContext context)
{
var options = new GeneratorOptions(context);
var defaultFieldModifier = options.AvaloniaNameGeneratorDefaultFieldModifier.ToString().ToLowerInvariant();
ICodeGenerator generator = options.AvaloniaNameGeneratorBehavior switch {
Behavior.OnlyProperties => new OnlyPropertiesCodeGenerator(),
Behavior.InitializeComponent => new InitializeComponentCodeGenerator(),
_ => throw new ArgumentOutOfRangeException()
};
var types = new RoslynTypeSystem((CSharpCompilation)context.Compilation);
var compiler = MiniCompiler.CreateDefault(types, MiniCompiler.AvaloniaXmlnsDefinitionAttribute);
return new AvaloniaNameGenerator(
new XamlXViewResolver(types, compiler, true, type => ReportInvalidType(context, type)),
new XamlXNameResolver(defaultFieldModifier),
generator);
}
private static void ReportUnhandledError(GeneratorExecutionContext context, Exception error) private static void ReportUnhandledError(GeneratorExecutionContext context, Exception error)
{ {
const string message = "Unhandled exception occured while generating typed Name references. " + const string message =
"Please file an issue: https://github.com/avaloniaui/avalonia.namegenerator"; "Unhandled exception occured while generating typed Name references. " +
"Please file an issue: https://github.com/avaloniaui/avalonia.namegenerator";
context.ReportDiagnostic( context.ReportDiagnostic(
Diagnostic.Create( Diagnostic.Create(
new DiagnosticDescriptor( new DiagnosticDescriptor(
@ -63,8 +66,9 @@ namespace Avalonia.NameGenerator
private static void ReportInvalidType(GeneratorExecutionContext context, string typeName) private static void ReportInvalidType(GeneratorExecutionContext context, string typeName)
{ {
var message = $"Avalonia x:Name generator was unable to generate names for type '{typeName}'. " + var message =
$"The type '{typeName}' does not exist in the assembly."; $"Avalonia x:Name generator was unable to generate names for type '{typeName}'. " +
$"The type '{typeName}' does not exist in the assembly.";
context.ReportDiagnostic( context.ReportDiagnostic(
Diagnostic.Create( Diagnostic.Create(
new DiagnosticDescriptor( new DiagnosticDescriptor(

2
src/Avalonia.NameGenerator/Generator.props

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

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

@ -9,6 +9,12 @@ namespace Avalonia.NameGenerator.Generator
internal class XamlXNameResolver : INameResolver, IXamlAstVisitor internal class XamlXNameResolver : INameResolver, IXamlAstVisitor
{ {
private readonly List<ResolvedName> _items = new(); private readonly List<ResolvedName> _items = new();
private readonly string _defaultFieldModifier;
public XamlXNameResolver(string defaultFieldModifier = "internal")
{
_defaultFieldModifier = defaultFieldModifier;
}
public IReadOnlyList<ResolvedName> ResolveNames(XamlDocument xaml) public IReadOnlyList<ResolvedName> ResolveNames(XamlDocument xaml)
{ {
@ -55,7 +61,7 @@ namespace Avalonia.NameGenerator.Generator
void IXamlAstVisitor.Pop() { } void IXamlAstVisitor.Pop() { }
private static string TryGetFieldModifier(XamlAstObjectNode objectNode) private string TryGetFieldModifier(XamlAstObjectNode objectNode)
{ {
// We follow Xamarin.Forms API behavior in terms of x:FieldModifier here: // We follow Xamarin.Forms API behavior in terms of x:FieldModifier here:
// https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/field-modifiers // https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/field-modifiers
@ -78,7 +84,7 @@ namespace Avalonia.NameGenerator.Generator
"protected" => "protected", "protected" => "protected",
"internal" => "internal", "internal" => "internal",
"notpublic" => "internal", "notpublic" => "internal",
_ => "internal" _ => _defaultFieldModifier
}; };
} }
} }

28
src/Avalonia.NameGenerator/GeneratorOptions.cs

@ -5,7 +5,16 @@ namespace Avalonia.NameGenerator
{ {
public enum BuildProperties public enum BuildProperties
{ {
AvaloniaNameGeneratorBehavior = 0 AvaloniaNameGeneratorBehavior = 0,
AvaloniaNameGeneratorDefaultFieldModifier = 1,
}
public enum DefaultFieldModifier
{
Public = 0,
Private = 1,
Internal = 2,
Protected = 3,
} }
public enum Behavior public enum Behavior
@ -29,10 +38,25 @@ namespace Avalonia.NameGenerator
nameof(BuildProperties.AvaloniaNameGeneratorBehavior), nameof(BuildProperties.AvaloniaNameGeneratorBehavior),
nameof(Behavior.OnlyProperties)); nameof(Behavior.OnlyProperties));
if (!Enum.TryParse(propertyValue, out Behavior behavior)) if (!Enum.TryParse(propertyValue, true, out Behavior behavior))
return Behavior.OnlyProperties; return Behavior.OnlyProperties;
return behavior; return behavior;
} }
} }
public DefaultFieldModifier AvaloniaNameGeneratorDefaultFieldModifier
{
get
{
var propertyValue = _context
.GetMSBuildProperty(
nameof(BuildProperties.AvaloniaNameGeneratorDefaultFieldModifier),
nameof(DefaultFieldModifier.Internal));
if (!Enum.TryParse(propertyValue, true, out DefaultFieldModifier modifier))
return DefaultFieldModifier.Internal;
return modifier;
}
}
} }
} }
Loading…
Cancel
Save