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:
Chris Hamons 2017-05-31 10:30:42 -05:00 коммит произвёл GitHub
Родитель 1d4c32dc04
Коммит 70e5a0f791
6 изменённых файлов: 93 добавлений и 78 удалений

30
objcgen/CachedValue.cs Normal file
Просмотреть файл

@ -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);