Skip to content

Commit 8417edd

Browse files
committed
[generator] Cache static final field values.
1 parent 51b784a commit 8417edd

File tree

4 files changed

+41
-10
lines changed

4 files changed

+41
-10
lines changed

Diff for: src/Xamarin.SourceWriter/Models/TypeReferenceWriter.cs

+9-4
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,17 @@ public TypeReferenceWriter (string ns, string name)
4040

4141
public virtual void WriteTypeReference (CodeWriter writer)
4242
{
43-
if (Namespace.HasValue ())
44-
writer.Write ($"{Namespace}.{Name}{NullableOperator} ");
45-
else
46-
writer.Write ($"{Name}{NullableOperator} ");
43+
writer.Write ($"{ToString ()} ");
4744
}
4845

4946
string NullableOperator => Nullable ? "?" : string.Empty;
47+
48+
public override string ToString ()
49+
{
50+
if (Namespace.HasValue ())
51+
return $"{Namespace}.{Name}{NullableOperator}";
52+
53+
return $"{Name}{NullableOperator}";
54+
}
5055
}
5156
}

Diff for: tools/generator/Java.Interop.Tools.Generator.ObjectModel/Field.cs

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public class Field : ApiVersionsSupport.IApiAvailability, ISourceLineInfo
4242

4343
public bool NeedsProperty => !IsStatic || !IsFinal || string.IsNullOrEmpty (Value) || Symbol.IsArray || !primitive_types.Contains (Symbol.JavaName);
4444

45+
public string CachedMemberName => $"_{Name}_cache";
46+
4547
public bool Validate (CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
4648
{
4749
Symbol = opt.SymbolTable.Lookup (TypeName, type_params);

Diff for: tools/generator/SourceWriters/BoundFieldAsProperty.cs

+29-6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class BoundFieldAsProperty : PropertyWriter
1616
{
1717
readonly Field field;
1818
readonly CodeGenerationOptions opt;
19+
readonly FieldWriter? cached_field;
1920

2021
public BoundFieldAsProperty (GenBase type, Field field, CodeGenerationOptions opt)
2122
{
@@ -59,10 +60,22 @@ public BoundFieldAsProperty (GenBase type, Field field, CodeGenerationOptions op
5960

6061
if (!field.IsConst)
6162
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+
};
6273
}
6374

6475
public override void Write (CodeWriter writer)
6576
{
77+
cached_field?.Write (writer);
78+
6679
// This is just a temporary hack to write the [GeneratedEnum] attribute before the // Metadata.xml
6780
// comment so that we are 100% equal to pre-refactor.
6881
var generated_attr = Attributes.OfType<GeneratedEnumAttr> ().FirstOrDefault ();
@@ -82,6 +95,13 @@ public override void WriteAttributes (CodeWriter writer)
8295

8396
protected override void WriteGetterBody (CodeWriter writer)
8497
{
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+
85105
writer.WriteLine ($"const string __id = \"{field.JavaName}.{field.Symbol.JniName}\";");
86106
writer.WriteLine ();
87107

@@ -93,24 +113,27 @@ protected override void WriteGetterBody (CodeWriter writer)
93113

94114
writer.WriteLine ($"var __v = {field.Symbol.ReturnCast}_members.{indirect}.{invoke} (__id{(field.IsStatic ? "" : ", this")});");
95115

116+
var cache_setter = cached_field is not null ? $"({PropertyType})({field.CachedMemberName} = " : "";
117+
var cache_setter_end = cached_field is not null ? ")" : "";
118+
96119
if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) {
97120
if (field.Symbol.NativeType == field.Symbol.FullName) {
98-
writer.WriteLine ("return __v;");
121+
writer.WriteLine ($"return {cache_setter}__v{cache_setter_end};");
99122
return;
100123
}
101-
writer.Write ("return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<");
124+
writer.Write ($"return {cache_setter}global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<");
102125
PropertyType.WriteTypeReference (writer);
103126
writer.Write (">(ref __v, JniObjectReferenceOptions.Copy)");
104-
writer.WriteLine (";");
127+
writer.WriteLine ($"{cache_setter_end};");
105128
return;
106129
}
107130

108131
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};");
110133
} 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};");
112135
} else {
113-
writer.WriteLine ("return __v;");
136+
writer.WriteLine ($"return {cache_setter}__v{cache_setter_end};");
114137
}
115138
}
116139

Diff for: tools/generator/generator.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>$(DotNetTargetFramework)</TargetFramework>
55
<OutputType>Exe</OutputType>
66
<DefineConstants>$(DefineConstants);GENERATOR;HAVE_CECIL;JCW_ONLY_TYPE_NAMES</DefineConstants>
7+
<Nullable>annotations</Nullable>
78
</PropertyGroup>
89

910
<Import Project="..\..\TargetFrameworkDependentValues.props" />

0 commit comments

Comments
 (0)