@@ -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,22 @@ 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
+ UseExplicitPrivateKeyword = type is InterfaceGen ,
72
+ } ;
62
73
}
63
74
64
75
public override void Write ( CodeWriter writer )
65
76
{
77
+ cached_field ? . Write ( writer ) ;
78
+
66
79
// This is just a temporary hack to write the [GeneratedEnum] attribute before the // Metadata.xml
67
80
// comment so that we are 100% equal to pre-refactor.
68
81
var generated_attr = Attributes . OfType < GeneratedEnumAttr > ( ) . FirstOrDefault ( ) ;
@@ -82,6 +95,13 @@ public override void WriteAttributes (CodeWriter writer)
82
95
83
96
protected override void WriteGetterBody ( CodeWriter writer )
84
97
{
98
+ var cached_field_type = cached_field is not null ? new TypeReferenceWriter ( cached_field . Type . Namespace , cached_field . Type . Name ) : null ;
99
+
100
+ if ( cached_field is not null ) {
101
+ writer . WriteLine ( $ "if ({ field . CachedMemberName } != null) return ({ cached_field_type } ){ field . CachedMemberName } ;") ;
102
+ writer . WriteLine ( ) ;
103
+ }
104
+
85
105
writer . WriteLine ( $ "const string __id = \" { field . JavaName } .{ field . Symbol . JniName } \" ;") ;
86
106
writer . WriteLine ( ) ;
87
107
@@ -93,24 +113,27 @@ protected override void WriteGetterBody (CodeWriter writer)
93
113
94
114
writer . WriteLine ( $ "var __v = { field . Symbol . ReturnCast } _members.{ indirect } .{ invoke } (__id{ ( field . IsStatic ? "" : ", this" ) } );") ;
95
115
116
+ var cache_setter = cached_field is not null ? $ "({ PropertyType } )({ field . CachedMemberName } = " : "" ;
117
+ var cache_setter_end = cached_field is not null ? ")" : "" ;
118
+
96
119
if ( opt . CodeGenerationTarget == CodeGenerationTarget . JavaInterop1 ) {
97
120
if ( field . Symbol . NativeType == field . Symbol . FullName ) {
98
- writer . WriteLine ( "return __v;" ) ;
121
+ writer . WriteLine ( $ "return { cache_setter } __v{ cache_setter_end } ;") ;
99
122
return ;
100
123
}
101
- writer . Write ( "return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<" ) ;
124
+ writer . Write ( $ "return { cache_setter } global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<") ;
102
125
PropertyType . WriteTypeReference ( writer ) ;
103
126
writer . Write ( ">(ref __v, JniObjectReferenceOptions.Copy)" ) ;
104
- writer . WriteLine ( " ;") ;
127
+ writer . WriteLine ( $ " { cache_setter_end } ;") ;
105
128
return ;
106
129
}
107
130
108
131
if ( field . Symbol . IsArray ) {
109
- writer . WriteLine ( $ "return global::Android.Runtime.JavaArray<{ opt . GetOutputName ( field . Symbol . ElementType ) } >.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef);") ;
132
+ writer . WriteLine ( $ "return { cache_setter } global::Android.Runtime.JavaArray<{ opt . GetOutputName ( field . Symbol . ElementType ) } >.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef){ cache_setter_end } ;") ;
110
133
} 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 ) ) } ;") ;
134
+ 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
135
} else {
113
- writer . WriteLine ( "return __v;" ) ;
136
+ writer . WriteLine ( $ "return { cache_setter } __v{ cache_setter_end } ;") ;
114
137
}
115
138
}
116
139
0 commit comments