55using System . Text ;
66
77using Microsoft . CodeAnalysis ;
8+ using Microsoft . CodeAnalysis . CSharp ;
89using Microsoft . CodeAnalysis . CSharp . Syntax ;
9- using Microsoft . CodeAnalysis . Text ;
1010
1111namespace SourceGenerators
1212{
@@ -23,19 +23,25 @@ public void Initialize(GeneratorInitializationContext context)
2323#endif
2424
2525 context . RegisterForPostInitialization ( i => i . AddSource ( "ToExprAttribute.g.cs" ,
26- @"// <auto-generated/>
27- using System;
26+ """
27+ // <auto-generated/>
28+ #pragma warning disable
29+ #nullable enable annotations
2830
29- namespace Linq.Expressions.Deconstruct
30- {
31- [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
32- [System.Diagnostics.Conditional(""ToExprGenerator_DEBUG"")]
33- sealed class ToExprAttribute : Attribute
34- {
35- public string PropertyName { get; set; }
36- public bool IsNullable { get; set; }
37- }
38- }" ) ) ;
31+ using System;
32+
33+ namespace Linq.Expressions.Deconstruct
34+ {
35+ [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
36+ [System.Diagnostics.Conditional("ToExprGenerator_DEBUG")]
37+ sealed class ToExprAttribute : Attribute
38+ {
39+ public string PropertyName { get; set; }
40+ public bool IsNullable { get; set; }
41+ }
42+ }
43+
44+ """ ) ) ;
3945
4046 context . RegisterForSyntaxNotifications ( ( ) => new SyntaxReceiver ( ) ) ;
4147 }
@@ -63,22 +69,29 @@ string ProcessClass(INamedTypeSymbol classSymbol, List<IFieldSymbol> fields, ISy
6369
6470 var namespaceName = classSymbol . ContainingNamespace . ToDisplayString ( ) ;
6571
66- var source = new StringBuilder ( $$ """
67- #nullable enable
72+ var source = new StringBuilder (
73+ $$ """
74+ // <auto-generated/>
75+ #pragma warning disable
76+ #nullable enable annotations
6877
69- namespace {{ namespaceName }}
70- {
71- partial class Expr
72- {
73- partial class {{ classSymbol . Name }}
74- {
75- """ ) ;
78+ using System;
79+
80+ #nullable enable
81+
82+ namespace {{ namespaceName }}
83+ {
84+ partial class Expr
85+ {
86+ partial class {{ classSymbol . Name }}
87+ {
88+
89+ """ ) ;
7690
7791 foreach ( var fieldSymbol in fields )
7892 ProcessField ( source , classSymbol , fieldSymbol , attributeSymbol ) ;
7993
8094 source
81- . AppendLine ( )
8295 . AppendLine ( " }" )
8396 . AppendLine ( " }" )
8497 . AppendLine ( "}" )
@@ -110,25 +123,29 @@ void ProcessField(StringBuilder source, INamedTypeSymbol classSymbol, IFieldSymb
110123 propertyName = overridenName . Value ! . ToString ( ) ;
111124 }
112125
113- if ( propertyName . Length == 0 || propertyName == fieldName )
126+ if ( propertyName . Length == 0 || propertyName == fieldName || classSymbol . MemberNames . Contains ( propertyName ) )
114127 {
115- source . AppendLine ( $ "#error Generator failed for : { fieldName } .") ;
116- return ;
117- }
128+ if ( fieldSymbol . Locations [ 0 ] is { Kind : LocationKind . SourceFile } location )
129+ {
130+ var ls = location . GetMappedLineSpan ( ) ;
131+ source
132+ . AppendLine ( $ "#line ({ ls . Span . Start . Line + 1 } ,{ ls . Span . Start . Character } )-({ ls . Span . End . Line + 1 } ,{ ls . Span . End . Character } ) \" { ls . Path } \" ")
133+ ;
134+ }
118135
119- // if the class doesn't implement INotifyPropertyChanged already, add it
120- if ( classSymbol . MemberNames . Contains ( propertyName ) )
121- {
122- source . AppendLine ( $ "#error Generator failed for : { fieldName } ." ) ;
136+ source
137+ . AppendLine ( $ "#error Generator failed on ' { fieldName } '." )
138+ . AppendLine ( "#line default" )
139+ ;
123140 return ;
124141 }
125142
126143 if ( isNullable . IsNull || isNullable . Value is false )
127144 fieldType = fieldType . TrimEnd ( '?' ) ;
128145
129146 source . Append ( $$ """
130-
131147 public {{ fieldType }} {{ propertyName }} => {{ fieldName }} ??= Expr.{{ propertyName }} .ToExpr();
148+
132149""" ) ;
133150 }
134151
@@ -138,7 +155,7 @@ public class SyntaxReceiver : ISyntaxContextReceiver
138155
139156 public void OnVisitSyntaxNode ( GeneratorSyntaxContext context )
140157 {
141- if ( context . Node is FieldDeclarationSyntax { AttributeLists . Count : > 0 } field )
158+ if ( context . Node is FieldDeclarationSyntax { AttributeLists : [ _ , .. ] } field )
142159 {
143160 foreach ( var variable in field . Declaration . Variables )
144161 {
0 commit comments