Skip to content
This repository has been archived by the owner on Jun 28, 2023. It is now read-only.

Commit

Permalink
fix: Don't break when one form is invalid (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
worldbeater authored Nov 6, 2022
1 parent c0226c2 commit fda0a3c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 58 deletions.
40 changes: 4 additions & 36 deletions src/Avalonia.NameGenerator/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void Execute(GeneratorExecutionContext context)
}
catch (Exception exception)
{
ReportUnhandledError(context, exception);
context.ReportUnhandledError(exception);
}
}

Expand All @@ -44,42 +44,10 @@ private static INameGenerator CreateNameGenerator(GeneratorExecutionContext cont
options.AvaloniaNameGeneratorViewFileNamingStrategy,
new GlobPatternGroup(options.AvaloniaNameGeneratorFilterByPath),
new GlobPatternGroup(options.AvaloniaNameGeneratorFilterByNamespace),
new XamlXViewResolver(types, compiler, true, type => ReportInvalidType(context, type)),
new XamlXViewResolver(types, compiler, true,
type => context.ReportInvalidType(type),
error => context.ReportUnhandledError(error)),
new XamlXNameResolver(options.AvaloniaNameGeneratorDefaultFieldModifier),
generator);
}

private static void ReportUnhandledError(GeneratorExecutionContext context, Exception error)
{
const string message =
"Unhandled exception occured while generating typed Name references. " +
"Please file an issue: https://github.com/avaloniaui/avalonia.namegenerator";
context.ReportDiagnostic(
Diagnostic.Create(
new DiagnosticDescriptor(
"AXN0002",
message,
error.ToString(),
"Usage",
DiagnosticSeverity.Error,
true),
Location.None));
}

private static void ReportInvalidType(GeneratorExecutionContext context, string typeName)
{
var message =
$"Avalonia x:Name generator was unable to generate names for type '{typeName}'. " +
$"The type '{typeName}' does not exist in the assembly.";
context.ReportDiagnostic(
Diagnostic.Create(
new DiagnosticDescriptor(
"AXN0001",
message,
message,
"Usage",
DiagnosticSeverity.Error,
true),
Location.None));
}
}
29 changes: 20 additions & 9 deletions src/Avalonia.NameGenerator/Generator/XamlXViewResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal class XamlXViewResolver : IViewResolver, IXamlAstVisitor
private readonly MiniCompiler _compiler;
private readonly bool _checkTypeValidity;
private readonly Action<string> _onTypeInvalid;
private readonly Action<Exception> _onUnhandledError;

private ResolvedView _resolvedClass;
private XamlDocument _xaml;
Expand All @@ -23,26 +24,36 @@ public XamlXViewResolver(
RoslynTypeSystem typeSystem,
MiniCompiler compiler,
bool checkTypeValidity = false,
Action<string> onTypeInvalid = null)
Action<string> onTypeInvalid = null,
Action<Exception> onUnhandledError = null)
{
_checkTypeValidity = checkTypeValidity;
_onTypeInvalid = onTypeInvalid;
_onUnhandledError = onUnhandledError;
_typeSystem = typeSystem;
_compiler = compiler;
}

public ResolvedView ResolveView(string xaml)
{
_resolvedClass = null;
_xaml = XDocumentXamlParser.Parse(xaml, new Dictionary<string, string>
try
{
{XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
});
_resolvedClass = null;
_xaml = XDocumentXamlParser.Parse(xaml, new Dictionary<string, string>
{
{XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
});

_compiler.Transform(_xaml);
_xaml.Root.Visit(this);
_xaml.Root.VisitChildren(this);
return _resolvedClass;
_compiler.Transform(_xaml);
_xaml.Root.Visit(this);
_xaml.Root.VisitChildren(this);
return _resolvedClass;
}
catch (Exception exception)
{
_onUnhandledError?.Invoke(exception);
return null;
}
}

IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node)
Expand Down
32 changes: 19 additions & 13 deletions src/Avalonia.NameGenerator/GeneratorContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Linq;
using System;
using Microsoft.CodeAnalysis;

namespace Avalonia.NameGenerator;

internal static class GeneratorContextExtensions
{
private const string SourceItemGroupMetadata = "build_metadata.AdditionalFiles.SourceItemGroup";
private const string UnhandledErrorDescriptorId = "AXN0002";
private const string InvalidTypeDescriptorId = "AXN0001";

public static string GetMsBuildProperty(
this GeneratorExecutionContext context,
Expand All @@ -16,15 +17,20 @@ public static string GetMsBuildProperty(
return value ?? defaultValue;
}

public static string[] GetMsBuildItems(this GeneratorExecutionContext context, string name)
=> context
.AdditionalFiles
.Where(f =>
context
.AnalyzerConfigOptions
.GetOptions(f)
.TryGetValue(SourceItemGroupMetadata, out var sourceItemGroup)
&& sourceItemGroup == name)
.Select(f => f.Path)
.ToArray();
public static void ReportUnhandledError(this GeneratorExecutionContext context, Exception error) =>
context.Report(UnhandledErrorDescriptorId,
"Unhandled exception occured while generating typed Name references. " +
"Please file an issue: https://github.com/avaloniaui/avalonia.namegenerator",
error.ToString());

public static void ReportInvalidType(this GeneratorExecutionContext context, string typeName) =>
context.Report(InvalidTypeDescriptorId,
$"Avalonia x:Name generator was unable to generate names for type '{typeName}'. " +
$"The type '{typeName}' does not exist in the assembly.");

private static void Report(this GeneratorExecutionContext context, string id, string title, string message = null) =>
context.ReportDiagnostic(
Diagnostic.Create(
new DiagnosticDescriptor(id, title, message ?? title, "Usage", DiagnosticSeverity.Error, true),
Location.None));
}

0 comments on commit fda0a3c

Please sign in to comment.