Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

AvaloniaNameGenerator throws XamlTransformException when visiting a property element for parent element with generic type parameters

Open busitech opened this issue 5 months ago • 5 comments

Describe the bug

The AvaloniaNameGenerator uses the TypeReferenceResolver when parsing markup files.

During parsing, when an element is found having an x:TypeArguments attribute and a property element, when the property element is visited the TypeReferenceResolver throws XamlTransformException: Unable to resolve type from namespace.

At the time of the exception, the declaring type for the property is what the TypeReferenceResolver is trying to resolve.

A property element is not allowed to have an x:TypeArguments attribute, so the TypeReferenceResolver naively tries to resolve the declaring class of the property with no type arguments, even when the declaring type on the property element and the type on the node above which has the x:TypeArguments are exactly the same name. This leads to the type not being found and the exception thrown.

To Reproduce

This markup easily reproduces the issue:

       <sandbox:RecordList x:TypeArguments="sandbox:Customer" x:Name="grid">
         <sandbox:RecordList.Columns>
           <sandbox:DataGridTextColumn Header="Name" />  
         </sandbox:RecordList.Columns>
       </sandbox:RecordList>

Expected behavior

The exception should not be thrown, because the x:TypeArguments from the parent node (the declaring type having the property) should be used when resolving the declaring type.

Environment

  • Avalonia-Version: built and tested from source, using the master branch, at commit https://github.com/AvaloniaUI/Avalonia/commit/fea57b920a3c835b4bada7dc409af619517e93e7

Additional context

Avalonia.Generators.dll!XamlX.Transform.Transformers.TypeReferenceResolver.ResolveTypeCore(XamlX.Transform.AstTransformationContext context, string xmlns, string name, bool isMarkupExtension, System.Collections.Generic.List<XamlX.Ast.XamlAstXmlTypeReference> typeArguments, XamlX.Ast.IXamlLineInfo lineInfo) Line 107	C#
Avalonia.Generators.dll!XamlX.Transform.Transformers.TypeReferenceResolver.ResolveType(XamlX.Transform.AstTransformationContext context, string xmlns, string name, bool isMarkupExtension, System.Collections.Generic.List<XamlX.Ast.XamlAstXmlTypeReference> typeArguments, XamlX.Ast.IXamlLineInfo lineInfo) Line 34	C#
Avalonia.Generators.dll!XamlX.Transform.Transformers.TypeReferenceResolver.ResolveType(XamlX.Transform.AstTransformationContext context, XamlX.Ast.XamlAstXmlTypeReference xmlref) Line 140	C#
Avalonia.Generators.dll!XamlX.Transform.Transformers.TypeReferenceResolver.Transform(XamlX.Transform.AstTransformationContext context, XamlX.Ast.IXamlAstNode node) Line 128	C#
Avalonia.Generators.dll!XamlX.Transform.AstTransformationContext.Visitor.VisitCore(XamlX.Transform.AstTransformationContext context, XamlX.Ast.IXamlAstNode node) Line 117	C#
Avalonia.Generators.dll!XamlX.Transform.AstTransformationContext.ContextXamlAstVisitor.Visit(XamlX.Ast.IXamlAstNode node) Line 64	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 101	C#	Avalonia.Generators.dll!XamlX.Ast.XamlAstNamePropertyReference.VisitChildren(XamlX.Ast.IXamlAstVisitor visitor) Line 151	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 111	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstXamlPropertyValueNode.VisitChildren(XamlX.Ast.IXamlAstVisitor visitor) Line 59	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 111	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.VisitList<XamlX.Ast.IXamlAstNode>(System.Collections.Generic.IList<XamlX.Ast.IXamlAstNode> list, XamlX.Ast.IXamlAstVisitor visitor) Line 125	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstObjectNode.VisitChildren(XamlX.Ast.IXamlAstVisitor visitor) Line 88	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 111	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.VisitList<XamlX.Ast.IXamlAstNode>(System.Collections.Generic.IList<XamlX.Ast.IXamlAstNode> list, XamlX.Ast.IXamlAstVisitor visitor) Line 125	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstObjectNode.VisitChildren(XamlX.Ast.IXamlAstVisitor visitor) Line 88	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 111	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.VisitList<XamlX.Ast.IXamlAstNode>(System.Collections.Generic.IList<XamlX.Ast.IXamlAstNode> list, XamlX.Ast.IXamlAstVisitor visitor) Line 125	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstObjectNode.VisitChildren(XamlX.Ast.IXamlAstVisitor visitor) Line 88	C#
Avalonia.Generators.dll!XamlX.Ast.XamlAstNode.Visit(XamlX.Ast.IXamlAstVisitor visitor) Line 111	C#
Avalonia.Generators.dll!XamlX.Transform.AstTransformationContext.Visit(XamlX.Ast.IXamlAstNode root, XamlX.Transform.IXamlAstTransformer transformer) Line 122	C#
Avalonia.Generators.dll!XamlX.Compiler.XamlCompiler<object, XamlX.Emit.IXamlEmitResult>.Transform(XamlX.Ast.XamlDocument doc) Line 73	C#
Avalonia.Generators.dll!Avalonia.Generators.Common.XamlXViewResolver.ResolveView(string xaml) Line 47	C#
Avalonia.Generators.dll!Avalonia.Generators.NameGenerator.AvaloniaNameGenerator.GenerateNameReferences.AnonymousMethod__4(<>f__AnonymousType1<<>f__AnonymousType0<Microsoft.CodeAnalysis.AdditionalText, string>, string> <>h__TransparentIdentifier1) Line 46	C#
System.Core.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<<>f__AnonymousType1<<>f__AnonymousType0<Microsoft.CodeAnalysis.AdditionalText, string>, string>, <>f__AnonymousType2<<>f__AnonymousType1<<>f__AnonymousType0<Microsoft.CodeAnalysis.AdditionalText, string>, string>, Avalonia.Generators.Common.Domain.ResolvedView>>.MoveNext()	Unknown
System.Core.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<<>f__AnonymousType2<<>f__AnonymousType1<<>f__AnonymousType0<Microsoft.CodeAnalysis.AdditionalText, string>, string>, Avalonia.Generators.Common.Domain.ResolvedView>, Avalonia.Generators.NameGenerator.GeneratedPartialClass>.MoveNext()	Unknown
Avalonia.Generators.dll!Avalonia.Generators.NameGenerator.AvaloniaNameSourceGenerator.Execute(Microsoft.CodeAnalysis.GeneratorExecutionContext context) Line 31	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.SourceGeneratorAdaptor.Initialize.AnonymousMethod__5_5(Microsoft.CodeAnalysis.SourceProductionContext productionContext, Microsoft.CodeAnalysis.SourceGeneratorAdaptor.GeneratorContextBuilder contextBuilder) Line 58	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.UserFunctionExtensions.WrapUserAction.AnonymousMethod__0(Microsoft.CodeAnalysis.SourceProductionContext input1, System.__Canon input2, System.Threading.CancellationToken token) Line 101	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.SourceOutputNode<Microsoft.CodeAnalysis.SourceGeneratorAdaptor.GeneratorContextBuilder>.UpdateStateTable(Microsoft.CodeAnalysis.DriverStateTable.Builder graphState, Microsoft.CodeAnalysis.NodeStateTable<(System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.GeneratedSourceText>, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic>)> previousTable, System.Threading.CancellationToken cancellationToken) Line 70	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.DriverStateTable.Builder.GetLatestStateTableForNode<(System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.GeneratedSourceText>, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic>)>(Microsoft.CodeAnalysis.IIncrementalGeneratorNode<(System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.GeneratedSourceText>, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic>)> source) Line 60	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.SourceOutputNode<System.__Canon>.AppendOutputs(Microsoft.CodeAnalysis.IncrementalExecutionContext context, System.Threading.CancellationToken cancellationToken) Line 100	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.GeneratorDriver.UpdateOutputs(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IIncrementalGeneratorOutputNode> outputNodes, Microsoft.CodeAnalysis.IncrementalGeneratorOutputKind outputKind, Microsoft.CodeAnalysis.GeneratorRunStateTable.Builder generatorRunStateBuilder, System.Threading.CancellationToken cancellationToken, Microsoft.CodeAnalysis.DriverStateTable.Builder driverStateBuilder) Line 318	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.GeneratorDriver.RunGeneratorsCore(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.DiagnosticBag diagnosticsBag, System.Threading.CancellationToken cancellationToken) Line 299	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.GeneratorDriver.RunGeneratorsAndUpdateCompilation(Microsoft.CodeAnalysis.Compilation compilation, out Microsoft.CodeAnalysis.Compilation outputCompilation, out System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic> diagnostics, System.Threading.CancellationToken cancellationToken) Line 57	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.CommonCompiler.RunGenerators(Microsoft.CodeAnalysis.Compilation input, Microsoft.CodeAnalysis.ParseOptions parseOptions, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISourceGenerator> generators, Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.AdditionalText> additionalTexts, Microsoft.CodeAnalysis.DiagnosticBag generatorDiagnostics) Line 822	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.CommonCompiler.CompileAndEmit(Microsoft.CodeAnalysis.TouchedFileLogger touchedFilesLogger, ref Microsoft.CodeAnalysis.Compilation compilation, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer> analyzers, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISourceGenerator> generators, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.AdditionalText> additionalTextFiles, Microsoft.CodeAnalysis.AnalyzerConfigSet analyzerConfigSet, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.AnalyzerConfigOptionsResult> sourceFileAnalyzerConfigOptions, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.EmbeddedText> embeddedTexts, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, Microsoft.CodeAnalysis.ErrorLogger errorLogger, System.Threading.CancellationToken cancellationToken, out System.Threading.CancellationTokenSource analyzerCts, out Microsoft.CodeAnalysis.Diagnostics.AnalyzerDriver analyzerDriver, out Microsoft.CodeAnalysis.GeneratorDriverTimingInfo? generatorTimingInfo) Line 1098	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.CommonCompiler.RunCore(System.IO.TextWriter consoleOutput, Microsoft.CodeAnalysis.ErrorLogger errorLogger, System.Threading.CancellationToken cancellationToken) Line 960	C#
Microsoft.CodeAnalysis.dll!Microsoft.CodeAnalysis.CommonCompiler.Run(System.IO.TextWriter consoleOutput, System.Threading.CancellationToken cancellationToken) Line 769	C#
csc.exe!Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.Run.AnonymousMethod__0(System.IO.TextWriter tw) Line 28	C#
csc.exe!Microsoft.CodeAnalysis.CommandLine.ConsoleUtil.RunWithUtf8Output<int>(System.Func<System.IO.TextWriter, int> func) Line 26	C#
csc.exe!Microsoft.CodeAnalysis.CSharp.CommandLine.Csc.Run(string[] args, Microsoft.CodeAnalysis.BuildPaths buildPaths, System.IO.TextWriter textWriter, Microsoft.CodeAnalysis.IAnalyzerAssemblyLoader analyzerLoader) Line 28	C#
csc.exe!Microsoft.CodeAnalysis.CommandLine.BuildClient.RunLocalCompilation(string[] arguments, Microsoft.CodeAnalysis.BuildPaths buildPaths, System.IO.TextWriter textWriter) Line 196	C#
csc.exe!Microsoft.CodeAnalysis.CommandLine.BuildClient.RunCompilation(System.Collections.Generic.IEnumerable<string> originalArguments, Microsoft.CodeAnalysis.BuildPaths buildPaths, System.IO.TextWriter textWriter, string pipeName) Line 162	C#
csc.exe!Microsoft.CodeAnalysis.CommandLine.BuildClient.Run(System.Collections.Generic.IEnumerable<string> arguments, Microsoft.CodeAnalysis.CommandLine.RequestLanguage language, Microsoft.CodeAnalysis.CommandLine.CompileFunc compileFunc, Microsoft.CodeAnalysis.CommandLine.CompileOnServerFunc compileOnServerFunc, Microsoft.CodeAnalysis.CommandLine.ICompilerServerLogger logger) Line 117	C#
csc.exe!Microsoft.CodeAnalysis.CSharp.CommandLine.Program.MainCore(string[] args) Line 37	C#
csc.exe!Microsoft.CodeAnalysis.CSharp.CommandLine.Program.Main(string[] args) Line 18	C#

busitech avatar Jan 27 '24 08:01 busitech

Can you test with nightly builds? It shouldn't be reproducible there.

maxkatz6 avatar Jan 27 '24 09:01 maxkatz6

The above test was run from a fresh checkout of the master branch, from within the Avalonia solution, by modifying the Generators.Sandbox project. The commit I used was fea57b920a3c835b4bada7dc409af619517e93e7

Let me know if there is a better branch to use for my test, or if that is equivalent with the nightly build.

busitech avatar Jan 27 '24 09:01 busitech

fyi: https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed

timunie avatar Jan 29 '24 08:01 timunie

In case there was any doubt, using a pre-built nightly package produces the same error as when I built from source.

busitech avatar Jan 30 '24 01:01 busitech

I have added two PRs for debugging and fixing:

https://github.com/AvaloniaUI/Avalonia/pull/14448

https://github.com/kekekeks/XamlX/pull/103

busitech avatar Feb 02 '24 05:02 busitech