88using System . Linq ;
99using System . Threading ;
1010using Microsoft . CodeAnalysis ;
11+ using Microsoft . CodeAnalysis . CSharp ;
1112using Microsoft . CodeAnalysis . CSharp . Syntax ;
1213using ReactiveUI . SourceGenerators . Extensions ;
1314using ReactiveUI . SourceGenerators . Helpers ;
@@ -59,14 +60,60 @@ public sealed partial class ReactiveGenerator
5960
6061 token . ThrowIfCancellationRequested ( ) ;
6162
62- var accessModifier = $ "{ propertySymbol . SetMethod ? . DeclaredAccessibility } set". ToLower ( ) ;
63- if ( accessModifier . StartsWith ( "public" , StringComparison . Ordinal ) )
63+ // Get Property AccessModifier.
64+ var propertyAccessModifier = propertySymbol . DeclaredAccessibility . ToString ( ) . ToLower ( ) ;
65+ if ( propertyAccessModifier ? . Contains ( "and" ) == true )
6466 {
65- accessModifier = "set" ;
67+ propertyAccessModifier = propertyAccessModifier . Replace ( "and" , " " ) ;
6668 }
67- else if ( accessModifier . Contains ( "and" ) )
69+ else if ( propertyAccessModifier ? . Contains ( "or" ) == true )
6870 {
69- accessModifier = accessModifier . Replace ( "and" , " " ) ;
71+ propertyAccessModifier = propertyAccessModifier . Replace ( "or" , " " ) ;
72+ }
73+
74+ token . ThrowIfCancellationRequested ( ) ;
75+
76+ // Get Set AccessModifier.
77+ var setAccessModifier = $ "{ propertySymbol . SetMethod ? . DeclaredAccessibility } set". ToLower ( ) ;
78+ if ( setAccessModifier . StartsWith ( "public" , StringComparison . Ordinal ) )
79+ {
80+ setAccessModifier = "set" ;
81+ }
82+ else if ( setAccessModifier ? . Contains ( "and" ) == true )
83+ {
84+ if ( setAccessModifier . Contains ( "protectedandinternal" ) )
85+ {
86+ setAccessModifier = setAccessModifier . Replace ( "protectedandinternal" , "private protected" ) ;
87+ }
88+ else
89+ {
90+ setAccessModifier = setAccessModifier . Replace ( "and" , " " ) ;
91+ }
92+ }
93+ else if ( setAccessModifier ? . Contains ( "or" ) == true )
94+ {
95+ setAccessModifier = setAccessModifier . Replace ( "or" , " " ) ;
96+ }
97+
98+ if ( propertyAccessModifier == "private" && setAccessModifier == "private set" )
99+ {
100+ setAccessModifier = "set" ;
101+ }
102+ else if ( propertyAccessModifier == "internal" && setAccessModifier == "internal set" )
103+ {
104+ setAccessModifier = "set" ;
105+ }
106+ else if ( propertyAccessModifier == "protected" && setAccessModifier == "protected set" )
107+ {
108+ setAccessModifier = "set" ;
109+ }
110+ else if ( propertyAccessModifier == "protected internal" && setAccessModifier == "protected internal set" )
111+ {
112+ setAccessModifier = "set" ;
113+ }
114+ else if ( propertyAccessModifier == "private protected" && setAccessModifier == "private protected set" )
115+ {
116+ setAccessModifier = "set" ;
70117 }
71118
72119 token . ThrowIfCancellationRequested ( ) ;
@@ -78,6 +125,12 @@ public sealed partial class ReactiveGenerator
78125
79126 var typeNameWithNullabilityAnnotations = propertySymbol . Type . GetFullyQualifiedNameWithNullabilityAnnotations ( ) ;
80127 var fieldName = propertySymbol . GetGeneratedFieldName ( ) ;
128+
129+ if ( context . SemanticModel . Compilation is CSharpCompilation compilation && compilation . LanguageVersion == LanguageVersion . Preview )
130+ {
131+ fieldName = "field" ;
132+ }
133+
81134 var propertyName = propertySymbol . Name ;
82135
83136 // Get the nullability info for the property
@@ -111,10 +164,11 @@ public sealed partial class ReactiveGenerator
111164 isReferenceTypeOrUnconstraindTypeParameter ,
112165 includeMemberNotNullOnSetAccessor ,
113166 forwardedAttributesString ,
114- accessModifier ,
167+ setAccessModifier ! ,
115168 inheritance ,
116169 useRequired ,
117- true ) ,
170+ true ,
171+ propertyAccessModifier ! ) ,
118172 builder . ToImmutable ( ) ) ;
119173 }
120174#endif
@@ -156,12 +210,12 @@ public sealed partial class ReactiveGenerator
156210
157211 // Get AccessModifier enum value from the attribute
158212 attributeData . TryGetNamedArgument ( "SetModifier" , out int accessModifierArgument ) ;
159- var accessModifier = accessModifierArgument switch
213+ var setAccessModifier = accessModifierArgument switch
160214 {
161215 1 => "protected set" ,
162216 2 => "internal set" ,
163217 3 => "private set" ,
164- 4 => "internal protected set" ,
218+ 4 => "protected internal set" ,
165219 5 => "private protected set" ,
166220 6 => "init" ,
167221 _ => "set" ,
@@ -236,10 +290,11 @@ public sealed partial class ReactiveGenerator
236290 isReferenceTypeOrUnconstraindTypeParameter ,
237291 includeMemberNotNullOnSetAccessor ,
238292 forwardedAttributesString ,
239- accessModifier ,
293+ setAccessModifier ,
240294 inheritance ,
241295 useRequired ,
242- false ) ,
296+ false ,
297+ "public" ) ,
243298 builder . ToImmutable ( ) ) ;
244299 }
245300
@@ -255,7 +310,7 @@ public sealed partial class ReactiveGenerator
255310 private static string GenerateSource ( string containingTypeName , string containingNamespace , string containingClassVisibility , string containingType , PropertyInfo [ ] properties )
256311 {
257312 // Get Parent class details from properties.ParentInfo
258- var ( parentClassDeclarationsString , closingBrackets ) = TargetInfo . GenerateParentClassDeclarations ( properties . Select ( p => p . TargetInfo . ParentInfo ) . ToArray ( ) ) ;
313+ var ( parentClassDeclarationsString , closingBrackets ) = TargetInfo . GenerateParentClassDeclarations ( [ .. properties . Select ( p => p . TargetInfo . ParentInfo ) ] ) ;
259314
260315 var classes = GenerateClassWithProperties ( containingTypeName , containingNamespace , containingClassVisibility , containingType , properties ) ;
261316
@@ -315,43 +370,47 @@ private static string GetPropertySyntax(PropertyInfo propertyInfo)
315370 return string . Empty ;
316371 }
317372
318- var fieldName = propertyInfo . FieldName ;
373+ var setFieldName = propertyInfo . FieldName ;
374+ var getFieldName = propertyInfo . FieldName ;
319375 if ( propertyInfo . FieldName == "value" )
320376 {
321- fieldName = "this.value" ;
377+ setFieldName = "this.value" ;
322378 }
323379
324380 var fieldSyntax = string . Empty ;
325381 var partialModifier = propertyInfo . IsProperty ? "partial " : string . Empty ;
326- if ( propertyInfo . IsProperty )
382+ if ( propertyInfo . IsProperty && propertyInfo . FieldName != "field" )
327383 {
328384 fieldSyntax = $ "private { propertyInfo . TypeNameWithNullabilityAnnotations } { propertyInfo . FieldName } ;";
329385 }
330386
387+ var accessModifier = propertyInfo . PropertyAccessModifier ;
388+ var setAccessModifier = propertyInfo . SetAccessModifier ;
389+
331390 var propertyAttributes = string . Join ( "\n " , AttributeDefinitions . ExcludeFromCodeCoverage . Concat ( propertyInfo . ForwardedAttributes ) ) ;
332391
333392 if ( propertyInfo . IncludeMemberNotNullOnSetAccessor || propertyInfo . IsReferenceTypeOrUnconstrainedTypeParameter )
334393 {
335394 return
336395$$ """
337396 {{ fieldSyntax }}
338- /// <inheritdoc cref="{{ fieldName }} "/>
397+ /// <inheritdoc cref="{{ setFieldName }} "/>
339398 {{ propertyAttributes }}
340- {{ propertyInfo . TargetInfo . TargetVisibility }} {{ propertyInfo . Inheritance }} {{ propertyInfo . UseRequired }} {{ partialModifier }} {{ propertyInfo . TypeNameWithNullabilityAnnotations }} {{ propertyInfo . PropertyName }}
399+ {{ accessModifier }} {{ propertyInfo . Inheritance }} {{ propertyInfo . UseRequired }} {{ partialModifier }} {{ propertyInfo . TypeNameWithNullabilityAnnotations }} {{ propertyInfo . PropertyName }}
341400 {
342- get => {{ propertyInfo . FieldName }} ;
343- [global::System.Diagnostics.CodeAnalysis.MemberNotNull("{{ fieldName }} ")]
344- {{ propertyInfo . AccessModifier }} => this.RaiseAndSetIfChanged(ref {{ fieldName }} , value);
401+ get => {{ getFieldName }} ;
402+ [global::System.Diagnostics.CodeAnalysis.MemberNotNull("{{ setFieldName }} ")]
403+ {{ setAccessModifier }} => this.RaiseAndSetIfChanged(ref {{ setFieldName }} , value);
345404 }
346405""" ;
347406 }
348407
349408 return
350409$$ """
351410 {{ fieldSyntax }}
352- /// <inheritdoc cref="{{ fieldName }} "/>
411+ /// <inheritdoc cref="{{ setFieldName }} "/>
353412 {{ propertyAttributes }}
354- {{ propertyInfo . TargetInfo . TargetVisibility }} {{ propertyInfo . Inheritance }} {{ partialModifier }} {{ propertyInfo . UseRequired }} {{ propertyInfo . TypeNameWithNullabilityAnnotations }} {{ propertyInfo . PropertyName }} { get => {{ propertyInfo . FieldName }} ; {{ propertyInfo . AccessModifier }} => this.RaiseAndSetIfChanged(ref {{ fieldName }} , value); }
413+ {{ accessModifier }} {{ propertyInfo . Inheritance }} {{ partialModifier }} {{ propertyInfo . UseRequired }} {{ propertyInfo . TypeNameWithNullabilityAnnotations }} {{ propertyInfo . PropertyName }} { get => {{ getFieldName }} ; {{ setAccessModifier }} => this.RaiseAndSetIfChanged(ref {{ setFieldName }} , value); }
355414""" ;
356415 }
357416}
0 commit comments