Ejemplo n.º 1
0
        private object CreateExpressionInternal(Expression expression, IEnumerable <ParameterExpression> parameters, IDictionary <string, object> parameterMappings, Type returnType)
        {
            var modelFuncVisitor = new ModelFuncExpressionVisitor();
            var modelFunc        = modelFuncVisitor.Visit(expression);

            var visitor = new TreeExtensionExpressionVisitor();

            visitor.Visit(modelFunc);
            var collectedParameterInfos = visitor.CollectParameterInfos();
            var parameterList           = visitor.ListParameters();

            var types = new Type[parameterList.Count + 1];
            var args  = new object[3 * parameterList.Count + 1];


            if (parameterMappings == null && modelFuncVisitor.ExtractParameters.Count > 0)
            {
                parameterMappings = new Dictionary <string, object>();
            }
            foreach (var ex in modelFuncVisitor.ExtractParameters)
            {
                parameterMappings.Add(ex.Parameter.Name, ModelNotifySystem.Instance.CreateExpression(ex.Value, parameters, parameterMappings));
            }

            var expressionLambda   = Expression.Lambda(modelFunc, parameterList);
            var expressionCompiled = expressionLambda.Compile();

            args[0] = expressionCompiled;
            for (int i = 0; i < parameterList.Count; i++)
            {
                var parameter = parameterList[i];
                types[i]        = parameter.Type;
                args[3 * i + 1] = CreateNotifyValue(parameter.Name, parameterMappings, parameter.Type);

                TreeExtensionExpressionVisitor.ParameterInfo parInfo;
                if (collectedParameterInfos.TryGetValue(parameter, out parInfo))
                {
                    args[3 * i + 3] = parInfo.Properties;
                    args[3 * i + 2] = parInfo.Anchors;
                }
                else
                {
                    args[3 * i + 3] = null;
                    args[3 * i + 2] = null;
                }
            }
            types[parameterList.Count] = returnType;

            var treeExtensionCallType = ObservableTreeExtensionCallTypes.Types[types.Length - 2].MakeGenericType(types);
            var constructor           = treeExtensionCallType.GetConstructors()[0];

#if DEBUG
            if (constructor == null)
            {
                System.Diagnostics.Debugger.Break();
            }
#endif
            return(constructor.Invoke(args));
        }
Ejemplo n.º 2
0
        private object CreateExpressionInternal(Expression expression, IEnumerable <ParameterExpression> parameters, IDictionary <string, object> parameterMappings, Type returnType)
        {
            var modelFuncVisitor = new ModelFuncExpressionVisitor();
            var modelFunc        = modelFuncVisitor.Visit(expression);

            var promotionVisitor        = new PromotionExpressionVisitor();
            var promotionExpression     = promotionVisitor.Visit(modelFunc);
            var collectedParameterInfos = promotionVisitor.CollectParameterInfos();
            var parametersNew           = promotionVisitor.ListParameters();

            var newExpression         = Expression.Lambda(promotionExpression, parametersNew);
            var newExpressionCompiled = newExpression.Compile();

            var types = new Type[parametersNew.Count + 1];
            var args  = new object[3 * parametersNew.Count + 1];

            args[0] = newExpressionCompiled;

            if (parameterMappings == null && modelFuncVisitor.ExtractParameters.Count > 0)
            {
                parameterMappings = new Dictionary <string, object>();
            }
            foreach (var ex in modelFuncVisitor.ExtractParameters)
            {
                parameterMappings.Add(ex.Parameter.Name, ModelNotifySystem.Instance.CreateExpression(ex.Value, parameters, parameterMappings));
            }

            for (int i = 0; i < parametersNew.Count; i++)
            {
                var parameter = parametersNew[i];

                var extraction = promotionVisitor.ExtractParameters.FirstOrDefault(ex => ex.Parameter == parameter);
                if (extraction.Parameter == null)
                {
                    // The parameter is an original parameter
                    args[3 * i + 1] = CreateNotifyValue(parameter.Name, parameterMappings, parameter.Type);
                    types[i]        = parameter.Type;
                }
                else
                {
                    var val = extraction.Value;
                    if (!typeof(IModelElement).IsAssignableFrom(val.Type) && !typeof(IEnumerableExpression).IsAssignableFrom(val.Type) && !typeof(INotifyEnumerable).IsAssignableFrom(val.Type))
                    {
                        throw new NotSupportedException("Currently, only extraction of parameters typed as model elements or notifiable collections is supported.");
                    }
                    args[3 * i + 1] = ModelNotifySystem.Instance.CreateExpression(val, parameters, parameterMappings);
                    types[i]        = val.Type;
                }
                PromotionExpressionVisitor.ParameterInfo parInfo;
                if (collectedParameterInfos.TryGetValue(parameter, out parInfo))
                {
                    args[3 * i + 2] = parInfo.Properties;
                    args[3 * i + 3] = parInfo.NeedsContainment;
                }
                else
                {
                    args[3 * i + 2] = null;
                    args[3 * i + 3] = false;
                }
            }
            types[types.Length - 1] = returnType;

            var promotionMethodCallType = promotionMethodCallTypes[types.Length - 2].MakeGenericType(types);
            var constructor             = promotionMethodCallType.GetConstructors()[0];

#if DEBUG
            if (constructor == null)
            {
                System.Diagnostics.Debugger.Break();
            }
#endif
            return(constructor.Invoke(args));
        }