aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/CompilerServices/CompilerServices.cs
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2015-09-03 12:48:04 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2015-09-03 12:48:04 +0200
commit6fd66d56dd5789eae345a517dc42f3488cf7aca6 (patch)
treed8668c1870fa1cb91edac7d3d788aeed174a4c1f /src/CompilerServices/CompilerServices.cs
parentfcfe9c2189fbbb00b0901b246e401b0f05413c7f (diff)
* GOLib.sln:
* GOLib.csproj: * GOLIBTest_0.cs: * GOLIBTest_fps.cs: * ReflexionExtensions.cs: * Label.cs: * test4.goml: * GenericStack.cs: * PrivateContainer.cs: * CompilerServices.cs: * Tests.csproj: * member.svg: * GOLIBTest_TypeViewer.cs: * tmpMembers.goml: * testTypeViewer.goml: Type viewer * Group.cs: * Window.cs: * GraphicObject.cs: set OnLayoutChanges to public * Point.cs: Implement length
Diffstat (limited to 'src/CompilerServices/CompilerServices.cs')
-rw-r--r--src/CompilerServices/CompilerServices.cs65
1 files changed, 63 insertions, 2 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs
index b1b08d5e..1aaeac99 100644
--- a/src/CompilerServices/CompilerServices.cs
+++ b/src/CompilerServices/CompilerServices.cs
@@ -4,6 +4,8 @@ using System.Reflection;
using System.Collections;
using System.Diagnostics;
using System.Linq;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
namespace go
@@ -37,6 +39,10 @@ namespace go
}
static int dynHandleCpt = 0;
+ /// <summary>
+ /// Compile events expression in GOML attributes
+ /// </summary>
+ /// <param name="es">Event binding details</param>
public static void CompileEventSource(DynAttribute es)
{
Type srcType = es.Source.GetType ();
@@ -154,6 +160,11 @@ namespace go
evtFi.SetValue(es.Source, del);
}
+ /// <summary>
+ /// Resolves GOML property bindings afler loading
+ /// </summary>
+ /// <param name="binding">Binding details</param>
+ /// <param name="_source">Data source for binding</param>
public static void ResolveBinding(DynAttribute binding, object _source)
{
object srcGO = null;
@@ -185,14 +196,28 @@ namespace go
throw new Exception ("Syntax error in binding, expected 'go dot member'");
}
+ if (srcGO == null) {
+ Debug.WriteLine ("Invalid Binding Source: " + binding.Value);
+ return;
+ }
Type srcType = srcGO.GetType ();
Type dstType = binding.Source.GetType ();
MemberInfo miSrc = srcType.GetMember (statement).FirstOrDefault ();
MemberInfo miDst = dstType.GetMember (binding.MemberName).FirstOrDefault ();
+ object srcVal = null; //value in source member
+
+ #region search for extensions methods if member not found in type
+ if (miSrc == null && !string.IsNullOrEmpty(statement))
+ {
+ Assembly a = Assembly.GetExecutingAssembly();
+ miSrc = CompilerServices.GetExtensionMethods(a, srcType).FirstOrDefault();
+ }
+ #endregion
+
#region initialize target with actual value
- object srcVal = null;
+
if (miSrc == null)
srcVal = srcGO;//if no member is provided for binding, source raw value is taken
else {
@@ -200,7 +225,13 @@ namespace go
srcVal = (miSrc as PropertyInfo).GetGetMethod ().Invoke (srcGO, null);
else if (miSrc.MemberType == MemberTypes.Field)
srcVal = (miSrc as FieldInfo).GetValue (srcGO);
- else
+ else if (miSrc.MemberType == MemberTypes.Method){
+ MethodInfo mthSrc = miSrc as MethodInfo;
+ if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))
+ srcVal = mthSrc.Invoke(null, new object[] {srcGO});
+ else
+ srcVal = mthSrc.Invoke(srcGO, null);
+ }else
throw new Exception ("unandled source member type for binding");
}
if (miDst.MemberType == MemberTypes.Property) {
@@ -363,6 +394,36 @@ namespace go
} while(fi == null);
return fi;
}
+
+ /// <summary>
+ /// Gets extension methods defined in assembley for extendedType
+ /// </summary>
+ /// <returns>Extension methods enumerable</returns>
+ /// <param name="assembly">Assembly</param>
+ /// <param name="extendedType">Extended type to search for</param>
+ public static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly,
+ Type extendedType)
+ {
+ IEnumerable<MethodInfo> query = null;
+ Type curType = extendedType;
+
+ do {
+ query = from type in assembly.GetTypes ()
+ where type.IsSealed && !type.IsGenericType && !type.IsNested
+ from method in type.GetMethods (BindingFlags.Static
+ | BindingFlags.Public | BindingFlags.NonPublic)
+ where method.IsDefined (typeof(ExtensionAttribute), false)
+ where method.GetParameters () [0].ParameterType == curType
+ select method;
+
+ if (query.Count() > 0)
+ break;
+
+ curType = curType.BaseType;
+ } while (curType != null);
+
+ return query;
+ }
}
}