@@ -16,6 +16,7 @@ public class BoundFieldAsProperty : PropertyWriter
16
16
{
17
17
readonly Field field ;
18
18
readonly CodeGenerationOptions opt ;
19
+ readonly FieldWriter ? cached_field ;
19
20
20
21
public BoundFieldAsProperty ( GenBase type , Field field , CodeGenerationOptions opt )
21
22
{
@@ -59,10 +60,23 @@ public BoundFieldAsProperty (GenBase type, Field field, CodeGenerationOptions op
59
60
60
61
if ( ! field . IsConst )
61
62
HasSet = true ;
63
+
64
+ // This is considerably harder to support if we don't have NRT, due to the
65
+ // differences in handling nullable value and reference types.
66
+ if ( field . IsConst && opt . SupportNullableReferenceTypes )
67
+ cached_field = new FieldWriter {
68
+ Name = field . CachedMemberName ,
69
+ Type = new TypeReferenceWriter ( fieldType . TrimEnd ( '?' ) ) { Nullable = true } ,
70
+ IsStatic = true ,
71
+ IsPrivate = true ,
72
+ UseExplicitPrivateKeyword = type is InterfaceGen ,
73
+ } ;
62
74
}
63
75
64
76
public override void Write ( CodeWriter writer )
65
77
{
78
+ cached_field ? . Write ( writer ) ;
79
+
66
80
// This is just a temporary hack to write the [GeneratedEnum] attribute before the // Metadata.xml
67
81
// comment so that we are 100% equal to pre-refactor.
68
82
var generated_attr = Attributes . OfType < GeneratedEnumAttr > ( ) . FirstOrDefault ( ) ;
@@ -82,6 +96,13 @@ public override void WriteAttributes (CodeWriter writer)
82
96
83
97
protected override void WriteGetterBody ( CodeWriter writer )
84
98
{
99
+ var cached_field_type = cached_field is not null ? new TypeReferenceWriter ( cached_field . Type . Namespace , cached_field . Type . Name ) : null ;
100
+
101
+ if ( cached_field is not null ) {
102
+ writer . WriteLine ( $ "if ({ field . CachedMemberName } != null) return ({ cached_field_type } ){ field . CachedMemberName } ;") ;
103
+ writer . WriteLine ( ) ;
104
+ }
105
+
85
106
writer . WriteLine ( $ "const string __id = \" { field . JavaName } .{ field . Symbol . JniName } \" ;") ;
86
107
writer . WriteLine ( ) ;
87
108
@@ -93,24 +114,27 @@ protected override void WriteGetterBody (CodeWriter writer)
93
114
94
115
writer . WriteLine ( $ "var __v = { field . Symbol . ReturnCast } _members.{ indirect } .{ invoke } (__id{ ( field . IsStatic ? "" : ", this" ) } );") ;
95
116
117
+ var cache_setter = cached_field is not null ? $ "({ PropertyType } )({ field . CachedMemberName } = " : "" ;
118
+ var cache_setter_end = cached_field is not null ? ")" : "" ;
119
+
96
120
if ( opt . CodeGenerationTarget == CodeGenerationTarget . JavaInterop1 ) {
97
121
if ( field . Symbol . NativeType == field . Symbol . FullName ) {
98
- writer . WriteLine ( "return __v;" ) ;
122
+ writer . WriteLine ( $ "return { cache_setter } __v{ cache_setter_end } ;") ;
99
123
return ;
100
124
}
101
- writer . Write ( "return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<" ) ;
125
+ writer . Write ( $ "return { cache_setter } global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<") ;
102
126
PropertyType . WriteTypeReference ( writer ) ;
103
127
writer . Write ( ">(ref __v, JniObjectReferenceOptions.Copy)" ) ;
104
- writer . WriteLine ( " ;") ;
128
+ writer . WriteLine ( $ " { cache_setter_end } ;") ;
105
129
return ;
106
130
}
107
131
108
132
if ( field . Symbol . IsArray ) {
109
- writer . WriteLine ( $ "return global::Android.Runtime.JavaArray<{ opt . GetOutputName ( field . Symbol . ElementType ) } >.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef);") ;
133
+ writer . WriteLine ( $ "return { cache_setter } global::Android.Runtime.JavaArray<{ opt . GetOutputName ( field . Symbol . ElementType ) } >.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef){ cache_setter_end } ;") ;
110
134
} else if ( field . Symbol . NativeType != field . Symbol . FullName ) {
111
- writer . WriteLine ( $ "return { field . Symbol . ReturnCast } { ( field . Symbol . FromNative ( opt , invokeType != "Object" ? "__v" : "__v.Handle" , true ) + opt . GetNullForgiveness ( field ) ) } ;") ;
135
+ writer . WriteLine ( $ "return { cache_setter } { field . Symbol . ReturnCast } { ( field . Symbol . FromNative ( opt , invokeType != "Object" ? "__v" : "__v.Handle" , true ) + opt . GetNullForgiveness ( field ) ) } { cache_setter_end } ;") ;
112
136
} else {
113
- writer . WriteLine ( "return __v;" ) ;
137
+ writer . WriteLine ( $ "return { cache_setter } __v{ cache_setter_end } ;") ;
114
138
}
115
139
}
116
140
0 commit comments