private CodeFunction FindCodeFunction(Project project, IBindingMethod bindingMethod) { return(GetBindingClassesIncludingPartialClasses(project) .Where(c => c.FullName == bindingMethod.Type.FullName) .SelectMany(c => c.GetFunctions()).FirstOrDefault( f => f.Name == bindingMethod.Name && BindingReflectionExtensions.MethodEquals(bindingMethod, new VsBindingMethod(f)))); }
private Expression GenerateMethodCall(MethodData method, ArgumentData target, IList <ArgumentData> args) { args = BindingReflectionExtensions.GetMethodArgs(method.IsExtensionMethod, target, args); var expressions = new Expression[args.Count]; for (int index = 0; index < args.Count; index++) { var data = args[index]; if (data.IsLambda) { _lambdaParameter = method.Parameters[index]; data.UpdateExpression(BuildExpression(data.Node)); _lambdaParameter = null; } expressions[index] = data.Expression; } var methodInfo = method.Build(args); expressions = ConvertParameters(methodInfo, expressions); if (method.IsExtensionMethod) { return(Expression.Call(null, methodInfo, expressions)); } return(Expression.Call(target.Expression, methodInfo, expressions)); }
private Expression TryGenerateMethodCall(IList <MethodData> methods, ArgumentData target, IList <ArgumentData> arguments) { if (methods == null || methods.Count == 0) { return(null); } var methodInfos = new List <MethodInfo>(methods.Count); var methodArgs = new List <Expression[]>(methods.Count); for (int i = 0; i < methods.Count; i++) { try { var method = methods[i]; var args = BindingReflectionExtensions.GetMethodArgs(method.IsExtensionMethod, target, arguments); var expressions = new Expression[args.Count]; for (int index = 0; index < args.Count; index++) { var data = args[index]; if (data.IsLambda) { _lambdaParameter = method.Parameters[index]; data.UpdateExpression(BuildExpression(data.Node)); _lambdaParameter = null; } expressions[index] = data.Expression; } var methodInfo = method.Build(args); if (methodInfo != null) { methodInfos.Add(methodInfo); methodArgs.Add(expressions); } } catch { ; } } bool resultHasParams; var resultIndex = TrySelectMethod(methodInfos, methodArgs, (i, args) => args[i].ToArrayEx(e => e.Type), out resultHasParams); if (resultIndex < 0) { return(null); } var result = methodInfos[resultIndex]; var resultArgs = methodArgs[resultIndex]; var resultParameters = result.GetParameters(); resultArgs = ConvertParameters(resultParameters, resultArgs, resultHasParams); return(Expression.Call(result.IsExtensionMethod() ? null : target.Expression, result, resultArgs)); }
private Expression BuildMemberExpression(IMemberExpressionNode expression) { if (expression.Member.Contains("(")) { return(BuildMethodCall(new MethodCallExpressionNode(expression.Target, expression.Member.Replace("(", string.Empty).Replace(")", string.Empty), null, null))); } if (expression.Target == null) { Expression value; if (!_lambdaParameters.TryGetValue(expression.Member, out value)) { throw BindingExceptionManager.UnexpectedExpressionNode(expression); } return(value); } var target = BuildExpression(expression.Target); var type = GetTargetType(ref target); var @enum = BindingReflectionExtensions.TryParseEnum(expression.Member, type); if (@enum != null) { return(Expression.Constant(@enum)); } if (type != null) { var bindingMember = BindingServiceProvider .MemberProvider .GetBindingMember(type, expression.Member, false, false); if (bindingMember != null) { var methodCall = Expression.Call(Expression.Constant(bindingMember, typeof(IBindingMemberInfo)), BindingMemberGetValueMethod, ExpressionReflectionManager.ConvertIfNeed(target, typeof(object), false), EmptyObjectArrayExpression); return(Expression.Convert(methodCall, bindingMember.Type)); } } var member = type.FindPropertyOrField(expression.Member, target == null); //Trying to get dynamic value. if (member == null) { return(Expression.Call(null, GetMemberValueDynamicMethod, ExpressionReflectionManager.ConvertIfNeed(target, typeof(object), false), Expression.Constant(expression.Member, typeof(string)))); } return(member is PropertyInfo ? Expression.Property(target, (PropertyInfo)member) : Expression.Field(target, (FieldInfo)member)); }
private static bool IsAssignableFrom(Type attachedMemberType, Type sourceType) { #if PCL_WINRT if (attachedMemberType.GetTypeInfo().IsGenericTypeDefinition&& BindingReflectionExtensions.FindCommonType(attachedMemberType, sourceType) != null) #else if (attachedMemberType.IsGenericTypeDefinition && BindingReflectionExtensions.FindCommonType(attachedMemberType, sourceType) != null) #endif { return(true); } return(attachedMemberType.IsAssignableFrom(sourceType)); }
public BindingMemberInfo(IBindingMemberInfo attachedIndexerMember, string path) { var accessor = new AttachedIndexerAccessor(attachedIndexerMember, BindingReflectionExtensions.GetIndexerValues(path, castType: typeof(string))); _getValueAccessor = accessor.GetValue; _setValueAccessor = accessor.SetValue; _indexerAttachedBindingMember = attachedIndexerMember; _memberType = attachedIndexerMember.MemberType; _type = attachedIndexerMember.Type; _canRead = attachedIndexerMember.CanRead; _canWrite = attachedIndexerMember.CanWrite; _canObserve = attachedIndexerMember.CanObserve; }
public BindingMemberInfo(string path, Type type) : this(path, BindingMemberType.Array, type.GetElementType()) { var indexes = BindingReflectionExtensions .GetIndexerValues(path, null, typeof(int)) .ToArrayEx(o => (int)o); var arrayAccessor = new ArrayAccessor(indexes); _getValueAccessorSingle = arrayAccessor.GetValue; _setValueAccessorSingleAction = arrayAccessor.SetValue; _canRead = true; _canWrite = true; _isSingleParameter = true; }
public BindingMemberInfo(string path, bool expandoObject) : this(path, BindingMemberType.Dynamic, typeof(object)) { object[] indexerValues = null; if (expandoObject) { _isSingleParameter = true; _getValueAccessorSingle = o => { object value; ((IDictionary <string, object>)o).TryGetValue(path, out value); return(value); }; _setValueAccessorSingleAction = (o, v) => ((IDictionary <string, object>)o)[path] = v; } else { if (path.StartsWith("[", StringComparison.Ordinal) || path.StartsWith("Item[", StringComparison.Ordinal)) { indexerValues = BindingReflectionExtensions.GetIndexerValues(path, castType: typeof(string)); } var accessor = new DynamicObjectAccessor(path, indexerValues); if (indexerValues == null) { _getValueAccessor = accessor.GetValue; _setValueAccessor = accessor.SetValue; } else { _getValueAccessor = accessor.GetValueIndex; _setValueAccessor = accessor.SetValueIndex; } _isDynamic = true; _canObserve = true; } _canRead = true; _canWrite = true; }
public object Invoke(IDataContext context, IList <object> sourceValues) { var key = new CacheKey(sourceValues.ToArrayEx(o => o == null ? null : o.GetType())); Func <object[], object> expression; lock (_expressionCache) { if (!_expressionCache.TryGetValue(key, out expression)) { try { _sourceValues = sourceValues; _parameters = new List <KeyValuePair <int, ParameterExpression> > { new KeyValuePair <int, ParameterExpression>(-1, DataContextParameter) }; _dataContext = context; expression = CreateDelegate(); _expressionCache[key] = expression; } finally { _lambdaParameter = null; _lambdaParameters.Clear(); _sourceValues = null; _parameters = null; _dataContext = null; } } } if (_isEmpty) { return(expression.Invoke(new object[] { context })); } return(expression.Invoke(BindingReflectionExtensions.InsertFirstArg(sourceValues, context))); }
protected virtual IBindingMemberInfo GetExplicitBindingMember([NotNull] Type sourceType, [NotNull] string path) { path = path.Trim(); if (typeof(IDynamicObject).IsAssignableFrom(sourceType) && path != AttachedMemberConstants.DataContext) { return(new BindingMemberInfo(path)); } int indexerCounts = 0; if (path.StartsWith("[") && path.EndsWith("]")) { indexerCounts = 1; for (int index = 0; index < path.Length; index++) { if (path[index] == ',') { indexerCounts++; } } } var types = BindingReflectionExtensions.SelfAndBaseTypes(sourceType); foreach (var type in types) { if (indexerCounts == 0) { PropertyInfo property = type.GetPropertyEx(path, PropertyFlags); if (property != null) { return(new BindingMemberInfo(path, property, sourceType)); } } else { PropertyInfo property = type .GetPropertiesEx(PropertyFlags) .FirstOrDefault(info => info.GetIndexParameters().Length == indexerCounts); if (property != null) { return(new BindingMemberInfo(path, property, sourceType)); } if (type.IsArray && type.GetArrayRank() == indexerCounts) { return(new BindingMemberInfo(path, type)); } } EventInfo @event = type.GetEventEx(path, EventFlags); if (@event != null) { return(new BindingMemberInfo(path, @event)); } FieldInfo field = type.GetFieldEx(path, FieldFlags); if (field != null) { return(new BindingMemberInfo(path, field, sourceType)); } } return(null); }
private object InvokeMethodInternal(object target, string methodName, object[] args, Type[] typeArgs) { var type = target.GetType(); var argTypes = GetArgTypes(args); var key = new CacheKey(argTypes); Func <object[], object> result = null; lock (this) { if (type == _type) { TryGetValue(key, out result); } } if (result != null) { return(result(BindingReflectionExtensions.InsertFirstArg(args, target))); } List <MethodInfo> methods; if (methodName == ReflectionExtensions.IndexerName) { methods = new List <MethodInfo>(); foreach (var property in type.GetPropertiesEx(MemberFlags.Public | MemberFlags.Instance)) { if (property.GetIndexParameters().Length == args.Length) { methods.AddIfNotNull(property.GetGetMethod(true)); } } } else { methods = BindingReflectionExtensions.GetExtensionsMethods(methodName, BindingServiceProvider.ResourceResolver.GetKnownTypes()); foreach (var method in type.GetMethodsEx(MemberFlags.Public | MemberFlags.Instance)) { try { if (method.Name == methodName) { methods.AddIfNotNull(BindingReflectionExtensions.ApplyTypeArgs(method, typeArgs)); } } catch { ; } } } bool hasParams; var resultIndex = TrySelectMethod(methods, argTypes, (i, types) => types, out hasParams); if (resultIndex >= 0) { var method = methods[resultIndex]; var parameters = argTypes.Select(t => (Expression)Expression.Parameter(t)).ToList(); var argExpressions = ConvertParameters(method.GetParameters(), parameters, hasParams); parameters.Insert(0, Expression.Parameter(type)); var compile = Expression.Lambda(Expression.Call(parameters[0], method, argExpressions), parameters.Cast <ParameterExpression>()).Compile(); var methodInfo = compile.GetType().GetMethodEx(nameof(Action.Invoke), MemberFlags.Public | MemberFlags.Instance); if (methodInfo == null) { result = compile.DynamicInvoke; } else { var del = ServiceProvider.ReflectionManager.GetMethodDelegate(methodInfo); result = objects => del(compile, objects); } } lock (this) { _type = type; this[key] = result; } if (result == null) { throw BindingExceptionManager.InvalidBindingMember(target.GetType(), methodName); } return(result(BindingReflectionExtensions.InsertFirstArg(args, target))); }
protected virtual IBindingMemberInfo GetExplicitBindingMember([NotNull] Type sourceType, [NotNull] string path) { path = path.Trim(); string[] indexerArgs = null; if (path.StartsWith("[", StringComparison.Ordinal) && path.EndsWith("]", StringComparison.Ordinal)) { indexerArgs = path .RemoveBounds() .Split(BindingReflectionExtensions.CommaSeparator, StringSplitOptions.RemoveEmptyEntries); } var types = BindingReflectionExtensions.SelfAndBaseTypes(sourceType); foreach (var type in types) { if (indexerArgs == null) { PropertyInfo property = type.GetPropertyEx(path, PropertyFlags); if (property != null) { return(new BindingMemberInfo(path, property, sourceType)); } } else { PropertyInfo candidate = null; int valueTypeCount = -1; foreach (var property in type.GetPropertiesEx(PropertyFlags)) { var indexParameters = property.GetIndexParameters(); if (indexParameters.Length != indexerArgs.Length) { continue; } try { int count = 0; for (int i = 0; i < indexParameters.Length; i++) { var arg = indexerArgs[i]; var paramType = indexParameters[i].ParameterType; if (arg.StartsWith("\"", StringComparison.Ordinal) && arg.EndsWith("\"", StringComparison.Ordinal)) { if (paramType != typeof(string)) { break; } } else { BindingServiceProvider.ValueConverter(Empty, paramType, arg); if (paramType.IsValueType()) { count++; } } } if (valueTypeCount < count) { candidate = property; valueTypeCount = count; } } catch { ; } } if (candidate != null) { return(new BindingMemberInfo(path, candidate, sourceType)); } if (type.IsArray && type.GetArrayRank() == indexerArgs.Length) { return(new BindingMemberInfo(path, type)); } } EventInfo @event = type.GetEventEx(path, EventFlags); if (@event != null) { return(new BindingMemberInfo(path, @event, null)); } FieldInfo field = type.GetFieldEx(path, FieldFlags); if (field != null) { return(new BindingMemberInfo(path, field, sourceType)); } } if (typeof(IDynamicObject).IsAssignableFrom(sourceType)) { return(new BindingMemberInfo(path, false)); } if (typeof(ExpandoObject).IsAssignableFrom(sourceType)) { return(new BindingMemberInfo(path, true)); } if (path.EndsWith(AttachedMemberConstants.ChangedEventPostfix, StringComparison.Ordinal)) { var memberName = path.Substring(0, path.Length - 7); var member = GetBindingMember(sourceType, memberName, false, false); if (member != null && member.CanObserve) { return(new BindingMemberInfo(path, null, member)); } } return(null); }
public object SetValue(object src, object[] args) { return(_member.SetValue(src, BindingReflectionExtensions.InsertFirstArg(args ?? MugenMvvmToolkit.Empty.Array <object>(), _indexes))); }