Improve ImplementMethod, remove invalidation, and cache freezing (#373)
- ImplementMethod now only takes one argument - Remove Invalidation hack - https://github.com/mono/Embeddinator-4000/issues/370 - Semi implement freezing. We now only cache after freezing. Later we can look at improved permissions or exceptions - https://github.com/mono/Embeddinator-4000/issues/371
This commit is contained in:
Родитель
1d4c32dc04
Коммит
70e5a0f791
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
|
||||
namespace Embeddinator
|
||||
{
|
||||
class CachedValue<T> where T : class
|
||||
{
|
||||
Func<T> CalculateProc;
|
||||
T LastCalculatedValue;
|
||||
|
||||
public bool IsFrozen { get; private set; }
|
||||
public void Freeze () => IsFrozen = true;
|
||||
|
||||
public CachedValue (Func<T> calculateProc)
|
||||
{
|
||||
CalculateProc = calculateProc;
|
||||
}
|
||||
|
||||
public T Value {
|
||||
get {
|
||||
if (IsFrozen) {
|
||||
if (LastCalculatedValue == null)
|
||||
LastCalculatedValue = CalculateProc ();
|
||||
return LastCalculatedValue;
|
||||
} else {
|
||||
return CalculateProc ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -326,6 +326,7 @@
|
|||
<Compile Include="system-check.cs" />
|
||||
<Compile Include="embedder.cs" />
|
||||
<Compile Include="utils.cs" />
|
||||
<Compile Include="CachedValue.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="support\" />
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace ObjC {
|
|||
|
||||
ProcessPotentialName (processedMethod);
|
||||
|
||||
processedMethod.Freeze ();
|
||||
yield return processedMethod;
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +73,7 @@ namespace ObjC {
|
|||
|
||||
ProcessPotentialName (processedProperty);
|
||||
|
||||
processedProperty.Freeze ();
|
||||
yield return processedProperty;
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +128,7 @@ namespace ObjC {
|
|||
if (duplicateNames.Contains (CreateStringRep(constructor)))
|
||||
processedConstructor.FallBackToTypeName = true;
|
||||
|
||||
processedConstructor.Freeze ();
|
||||
yield return processedConstructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace ObjC {
|
|||
implementation.WriteLine ();
|
||||
|
||||
foreach (var mi in methods) {
|
||||
ImplementMethod (mi.Method, mi.Method.Name.CamelCase (), mi, isExtension: true);
|
||||
ImplementMethod (mi);
|
||||
}
|
||||
|
||||
headers.WriteLine ("@end");
|
||||
|
@ -791,11 +791,11 @@ namespace ObjC {
|
|||
var spacing = property_type [property_type.Length - 1] == '*' ? string.Empty : " ";
|
||||
headers.WriteLine ($") {property_type}{spacing}{property.Name};");
|
||||
|
||||
ImplementMethod (getter.Method, property.GetterName, property.GetMethod, pi: property.Property);
|
||||
ImplementMethod (property.GetMethod);
|
||||
if (setter == null)
|
||||
return;
|
||||
|
||||
ImplementMethod (setter.Method, property.SetterName, property.SetMethod, pi: property.Property);
|
||||
ImplementMethod (property.SetMethod);
|
||||
}
|
||||
|
||||
protected void Generate (ProcessedFieldInfo field)
|
||||
|
@ -905,24 +905,19 @@ namespace ObjC {
|
|||
}
|
||||
|
||||
// TODO override with attribute ? e.g. [ObjC.Selector ("foo")]
|
||||
// HACK - This should take a ProcessedMethod and not much of this stuff - https://github.com/mono/Embeddinator-4000/issues/276
|
||||
string ImplementMethod (MethodInfo info, string name, ProcessedMethod method, bool isExtension = false, PropertyInfo pi = null)
|
||||
string ImplementMethod (ProcessedMethod method)
|
||||
{
|
||||
MethodInfo info = method.Method;
|
||||
|
||||
var type = info.DeclaringType;
|
||||
var managed_type_name = NameGenerator.GetObjCName (type);
|
||||
|
||||
if (method.NameOverride == null)
|
||||
method.NameOverride = name;
|
||||
|
||||
method.IsExtension = isExtension;
|
||||
|
||||
method.Invalidate ();
|
||||
string objcsig = method.ObjCSignature;
|
||||
|
||||
var builder = new MethodHelper (headers, implementation) {
|
||||
AssemblySafeName = type.Assembly.GetName ().Name.Sanitize (),
|
||||
IsStatic = info.IsStatic,
|
||||
IsExtension = isExtension,
|
||||
IsExtension = method.IsExtension,
|
||||
ReturnType = GetReturnType (type, info.ReturnType),
|
||||
ManagedTypeName = type.FullName,
|
||||
MetadataToken = info.MetadataToken,
|
||||
|
@ -933,7 +928,7 @@ namespace ObjC {
|
|||
IsVirtual = info.IsVirtual && !info.IsFinal,
|
||||
};
|
||||
|
||||
if (pi == null)
|
||||
if (!method.IsPropertyImplementation)
|
||||
builder.WriteHeaders ();
|
||||
|
||||
builder.BeginImplementation ();
|
||||
|
@ -943,7 +938,7 @@ namespace ObjC {
|
|||
string postInvoke = String.Empty;
|
||||
var args = "nil";
|
||||
if (parametersInfo.Length > 0) {
|
||||
Generate (parametersInfo, isExtension, out postInvoke);
|
||||
Generate (parametersInfo, method.IsExtension, out postInvoke);
|
||||
args = "__args";
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1029,7 @@ namespace ObjC {
|
|||
builder = new EquatableHelper (method, headers, implementation);
|
||||
break;
|
||||
default:
|
||||
ImplementMethod (method.Method, method.BaseName, method);
|
||||
ImplementMethod (method);
|
||||
return;
|
||||
}
|
||||
builder.WriteHeaders ();
|
||||
|
|
|
@ -307,7 +307,7 @@ namespace ObjC {
|
|||
extmethods = new List<ProcessedMethod> ();
|
||||
extensions.Add (extended_type, extmethods);
|
||||
}
|
||||
extmethods.Add (new ProcessedMethod (mi, this));
|
||||
extmethods.Add (new ProcessedMethod (mi, this) { IsExtension = true } );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,51 +154,34 @@ namespace Embeddinator {
|
|||
public abstract class ProcessedMemberWithParameters : ProcessedMemberBase {
|
||||
public ProcessedMemberWithParameters (Processor processor) : base (processor)
|
||||
{
|
||||
objCSignature = new CachedValue<string> (GetObjcSignature);
|
||||
monoSignature = new CachedValue<string> (GetMonoSignature);
|
||||
}
|
||||
|
||||
public abstract string BaseName { get; }
|
||||
|
||||
public ParameterInfo[] Parameters { get; protected set; }
|
||||
|
||||
[Obsolete] // https://github.com/mono/Embeddinator-4000/issues/370
|
||||
public void Invalidate ()
|
||||
{
|
||||
objCSignature = null;
|
||||
monoSignature = null;
|
||||
}
|
||||
|
||||
string objCSignature;
|
||||
public string ObjCSignature {
|
||||
get {
|
||||
if (objCSignature == null)
|
||||
ComputeSignatures ();
|
||||
return objCSignature;
|
||||
}
|
||||
protected set {
|
||||
objCSignature = value;
|
||||
}
|
||||
}
|
||||
|
||||
string monoSignature;
|
||||
public string MonoSignature {
|
||||
get {
|
||||
if (monoSignature == null)
|
||||
ComputeSignatures ();
|
||||
return monoSignature;
|
||||
}
|
||||
protected set {
|
||||
monoSignature = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void ComputeSignatures ();
|
||||
|
||||
public int FirstDefaultParameter { get; set; }
|
||||
|
||||
protected abstract string GetObjcSignature ();
|
||||
CachedValue<string> objCSignature;
|
||||
public string ObjCSignature => objCSignature.Value;
|
||||
|
||||
protected abstract string GetMonoSignature ();
|
||||
CachedValue<string> monoSignature;
|
||||
public string MonoSignature => monoSignature.Value;
|
||||
|
||||
public void Freeze ()
|
||||
{
|
||||
objCSignature.Freeze ();
|
||||
monoSignature.Freeze ();
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessedMethod : ProcessedMemberWithParameters {
|
||||
public MethodInfo Method { get; private set; }
|
||||
public bool IsOperator { get; set; }
|
||||
public bool IsPropertyImplementation { get; set; }
|
||||
|
||||
public string NameOverride { get; set; }
|
||||
public string ManagedName { get; set; }
|
||||
|
@ -223,15 +206,9 @@ namespace Embeddinator {
|
|||
FirstDefaultParameter = -1;
|
||||
}
|
||||
|
||||
protected override void ComputeSignatures ()
|
||||
{
|
||||
ObjCSignature = GetObjcSignature ();
|
||||
MonoSignature = GetMonoSignature ();
|
||||
}
|
||||
|
||||
public override string ToString () => ToString (Method);
|
||||
|
||||
string GetMonoSignature ()
|
||||
protected override string GetMonoSignature ()
|
||||
{
|
||||
var mono = new StringBuilder (Method.Name);
|
||||
|
||||
|
@ -249,7 +226,7 @@ namespace Embeddinator {
|
|||
return mono.ToString ();
|
||||
}
|
||||
|
||||
string GetObjcSignature ()
|
||||
protected override string GetObjcSignature ()
|
||||
{
|
||||
string objName = BaseName;
|
||||
|
||||
|
@ -290,14 +267,20 @@ namespace Embeddinator {
|
|||
public ProcessedProperty (PropertyInfo property, Processor processor) : base (processor)
|
||||
{
|
||||
Property = property;
|
||||
|
||||
var g = Property.GetGetMethod ();
|
||||
if (g != null)
|
||||
GetMethod = new ProcessedMethod (g, Processor);
|
||||
|
||||
var s = Property.GetSetMethod ();
|
||||
if (s != null)
|
||||
SetMethod = new ProcessedMethod (s, Processor);
|
||||
getMethod = new CachedValue<ProcessedMethod> (() => {
|
||||
var getter = Property.GetGetMethod ();
|
||||
if (getter != null) {
|
||||
return new ProcessedMethod (getter, Processor) { NameOverride = GetterName, IsPropertyImplementation = true };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
setMethod = new CachedValue<ProcessedMethod> (() => {
|
||||
var setter = Property.GetSetMethod ();
|
||||
if (setter != null) {
|
||||
return new ProcessedMethod (setter, Processor) { NameOverride = SetterName, IsPropertyImplementation = true };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public override string ToString () => Property.ToString ();
|
||||
|
@ -305,8 +288,8 @@ namespace Embeddinator {
|
|||
public string Name => NameOverride != null ? NameOverride : Property.Name.CamelCase ();
|
||||
public string NameOverride { get; set; }
|
||||
|
||||
public bool HasGetter => GetMethod != null;
|
||||
public bool HasSetter => SetMethod != null;
|
||||
public bool HasGetter => Property.GetGetMethod () != null;
|
||||
public bool HasSetter => Property.GetSetMethod () != null;
|
||||
|
||||
public string GetterName {
|
||||
get {
|
||||
|
@ -324,8 +307,17 @@ namespace Embeddinator {
|
|||
}
|
||||
}
|
||||
|
||||
public ProcessedMethod GetMethod { get; private set; }
|
||||
public ProcessedMethod SetMethod { get; private set; }
|
||||
CachedValue<ProcessedMethod> getMethod;
|
||||
public ProcessedMethod GetMethod => getMethod.Value;
|
||||
|
||||
CachedValue<ProcessedMethod> setMethod;
|
||||
public ProcessedMethod SetMethod => setMethod.Value;
|
||||
|
||||
public void Freeze ()
|
||||
{
|
||||
getMethod.Freeze ();
|
||||
setMethod.Freeze ();
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConstructorType {
|
||||
|
@ -354,15 +346,9 @@ namespace Embeddinator {
|
|||
FirstDefaultParameter = -1;
|
||||
}
|
||||
|
||||
protected override void ComputeSignatures ()
|
||||
{
|
||||
ObjCSignature = GetObjcSignature ();
|
||||
MonoSignature = GetMonoSignature ();
|
||||
}
|
||||
|
||||
public override string ToString () => ToString (Constructor);
|
||||
|
||||
string GetMonoSignature ()
|
||||
protected override string GetMonoSignature ()
|
||||
{
|
||||
var mono = new StringBuilder (Constructor.Name);
|
||||
|
||||
|
@ -380,7 +366,7 @@ namespace Embeddinator {
|
|||
return mono.ToString ();
|
||||
}
|
||||
|
||||
string GetObjcSignature ()
|
||||
protected override string GetObjcSignature ()
|
||||
{
|
||||
var objc = new StringBuilder (BaseName);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче